Bagaimana memaksa melihat orientasi pengontrol di iOS 8?


149

Sebelum iOS 8, kami menggunakan kode di bawah ini dalam hubungannya dengan metode InterfaceOrientations yang didukung dan metode delegasi shouldAutoRotate untuk memaksa orientasi aplikasi ke orientasi tertentu. Saya menggunakan potongan kode di bawah ini untuk memutar aplikasi ke orientasi yang diinginkan. Pertama, saya mengubah orientasi bilah status. Dan kemudian hanya menampilkan dan segera menolak tampilan modal memutar tampilan ke orientasi yang diinginkan.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

Tapi ini gagal di iOS 8. Juga, saya telah melihat beberapa jawaban di stack overflow di mana orang menyarankan agar kita selalu menghindari pendekatan ini dari iOS 8 dan seterusnya.

Untuk lebih spesifik, aplikasi saya adalah tipe aplikasi universal. Ada tiga pengontrol secara total.

  1. Pengontrol Tampilan Pertama - Ini harus mendukung semua orientasi di iPad dan hanya potret (tombol home down) di iPhone.

  2. Pengontrol Tampilan Kedua - Seharusnya hanya mendukung lansekap tepat di semua kondisi

  3. Pengontrol Tampilan Ketiga - Seharusnya hanya mendukung lanskap tepat di semua kondisi

Kami menggunakan pengontrol navigasi untuk navigasi halaman. Dari pengontrol tampilan pertama, pada aksi klik tombol, kami mendorong yang kedua pada stack. Jadi, ketika pengontrol tampilan kedua tiba, terlepas dari orientasi perangkat, aplikasi hanya akan mengunci lansekap.

Di bawah ini adalah saya shouldAutorotatedan supportedInterfaceOrientationsmetode di controller tampilan kedua dan ketiga.

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

Apakah ada solusi untuk ini atau cara yang lebih baik untuk mengunci view controller dalam orientasi tertentu untuk iOS 8. Tolong bantu !!


Menerapkan metode yang Anda sebutkan di VC yang disajikan umumnya akan berfungsi (setidaknya itulah pengalaman saya di iOS 8). Mungkin pengaturan spesifik Anda menyebabkan masalah?
Vladimir Gritsenko

Mungkin saya bisa membuat pertanyaan sedikit lebih jelas. Saya akan mengedit pertanyaan sedikit.
Rashmi Ranjan mallick

@VladimirGritsenko: Silakan periksa sekarang. Saya sudah mengeditnya.
Rashmi Ranjan mallick

Kode dalam pertanyaan tidak menggunakan tumpukan pengontrol navigasi, melainkan presentasi modal, jadi masih belum jelas apa yang Anda lakukan sebenarnya. Saya akan mengatakan bahwa dalam kode kami, mengembalikan YA dari shouldAutoRotate dan mengembalikan orientasi yang diinginkan dari didukungInterfaceOrientations dalam VC yang disajikan dengan benar mengarahkan kepada VC.
Vladimir Gritsenko

Ya, itu bukan benar-benar gagal, itu hanya perubahan besar dalam konsep. Apakah itu perubahan yang baik sepenuhnya merupakan topik lain.
Kegluneq

Jawaban:


315

Untuk iOS 7 - 10:

Tujuan-C:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

Swift 3:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()

Sebut saja di - viewDidAppear:pengontrol tampilan yang disajikan.


61
Ini bukan API pribadi. Ini adalah penggunaan API yang tidak aman . Anda tidak menggunakan metode pribadi apa pun, tetapi menggunakan 'hal-hal internal'. Jika Apple mengubah nilai untuk "orientasi", itu gagal. Lebih buruk: jika Apple mengubah arti dari nilai "orientasi", Anda tidak tahu apa yang Anda ubah dengan mengatur nilainya.
sonxurxo

4
Untuk animasi menonaktifkan, dimasukkan [UIView setAnimationsEnabled:NO];dalam viewWillAppeardan [UIView setAnimationsEnabled:YES];di viewDidAppear, terkait: stackoverflow.com/a/6292506/88597
ohho

3
Peretasan yang bagus, tetapi masalah dengan itu, adalah tidak memecat didRotateFromInterfaceOrientation setelah menetapkan nilai orientasi baru (mendesah)
loretoparisi

2
Di iOS 9.2, ini hanya mengubah orientasi tetapi tidak mengunci.
Mark13426

2
Untuk semua orang yang berperilaku baik 90% dari waktu dan buggy 10% lainnya dari waktu, sebut ini setelah menetapkan kunci orientasi:[UINavigationController attemptRotationToDeviceOrientation];
Albert Renshaw

93

Rotasi orientasi sedikit lebih rumit jika Anda berada di dalam UINavigationControlleratau UITabBarController. Masalahnya adalah bahwa jika pengendali tampilan tertanam di salah satu pengendali ini, pengendali navigasi atau tab bar akan diutamakan dan membuat keputusan tentang autorotation dan orientasi yang didukung.

Saya menggunakan 2 ekstensi berikut pada UINavigationController dan UITabBarController sehingga melihat pengontrol yang tertanam di salah satu pengontrol ini bisa membuat keputusan.

Berikan View Controllers the Power!

Cepat 2.3

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

extension UITabBarController {
    public override func supportedInterfaceOrientations() -> Int {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

Cepat 3

extension UINavigationController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return visibleViewController?.supportedInterfaceOrientations ?? super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        return visibleViewController?.shouldAutorotate ?? super.shouldAutorotate
    }
}

extension UITabBarController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

Sekarang Anda dapat mengganti supportedInterfaceOrientationsmetode atau menimpa shouldAutoRotatedi pengontrol tampilan yang ingin dikunci jika tidak, Anda dapat mengabaikan penggantian di pengontrol tampilan lain yang ingin Anda warisi perilaku orientasi default yang ditentukan dalam daftar aplikasi Anda

Nonaktifkan Rotasi

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

Kunci ke Orientasi Tertentu

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

Secara teori ini harus bekerja untuk semua hierarki pengendali tampilan yang kompleks, tapi saya perhatikan ada masalah dengan UITabBarController. Untuk beberapa alasan ia ingin menggunakan nilai orientasi default. Lihat posting blog berikut jika Anda tertarik mempelajari cara mengatasi beberapa masalah:

Kunci Rotasi Layar


1
Saya tahu ini adalah posting yang sangat lama tetapi di mana Anda akan meletakkan kode ekstensi?
dwinnbrown

7
Menandai ke bawah untuk jawaban Swift hanya pada pertanyaan Objective-C.
Charlie Scott-Skinner

17
Ini adalah solusi yang bagus untuk Swift dan ObjC. Tidak mengerti mengapa orang memilih. Anda mendapat ide dan kemudian menulis kode itu mudah. Mengapa mengeluh?
Zhao

2
@Krodak, Pada ekstensi coba ubah "-> Int" ke "-> UIInterfaceOrientationMask". Apakah trik untuk saya.
the_pantless_coder

2
Gagasan dan kodenya sempurna, saya menyukainya, tetapi ada masalah saat menggunakan UINavigationController, dan kembali dari UIViewController dalam ditampilkan dalam lanskap ke salah satu yang harus ditampilkan dalam potret. Ada ide?
crisisGriega

24

Inilah yang bekerja untuk saya:

https://developer.apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

Sebut saja di metode viewDidAppear: Anda.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [UIViewController attemptRotationToDeviceOrientation];
}

3
Sangat berguna, jika perangkat sudah diputar dan Anda perlu memutar pengontrol tampilan Anda
avdyushin

2
Jawaban yang bagus Ketika digunakan bersama dengan jawaban yang diterima, ini berfungsi baik untuk saya setiap kali di Swift dan iOS 9+.
AndyDunn

1
Meskipun saya pikir itu bukan jawaban untuk pertanyaan yang diajukan, tetapi itu benar-benar membantu saya.
Abdurrahman Mubeen Ali

21

Saya menemukan bahwa jika itu adalah pengontrol tampilan yang disajikan, Anda dapat menimpanya preferredInterfaceOrientationForPresentation

Cepat:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
  return false
}

4
Tampaknya jawaban yang diterima hanya memicu perubahan orientasi ke lanskap. Apa yang Anda perlihatkan di sini adalah bagaimana memaksa pengontrol tampilan hanya berada di lanskap, dan tidak memengaruhi pengontrol tampilan presentasi (yang persis seperti yang saya butuhkan). Terima kasih.
Clifton Labrum

1
@CliftonLabrum apakah Anda melakukan hal lain untuk memaksa hanya lansekap? Menggunakan kode yang sama, pengontrol tampilan masih dapat memutar ke orientasi lain.
Crashalot

Saya kemudian menyadari bahwa - Anda benar. Saya belum menemukan perbaikan.
Clifton Labrum

1
Ini berhasil untuk saya. Saya dapat mempertahankan View Controller tunggal dalam mode Portrait dengan menggunakan kode ini (mengganti Landscape dengan Portrait). +1
Mark Barrasso

Iya! Ini juga berfungsi untuk saya di Xcode 7.3 & Swift 2.2. Tetapi masih perlu mendefinisikan aplikasi func untuk didukungInterfaceOrientationsForWindow di AppDelegate.
charles.cc.hsu

15

Cara ini cocok untuk saya di Swift 2 iOS 8.x:

PS (metode ini tidak perlu mengesampingkan fungsi orientasi seperti shouldautorotate pada setiap viewController, cukup satu metode di AppDelegate)

Periksa "memerlukan layar penuh" di info umum proyek Anda. masukkan deskripsi gambar di sini

Jadi, di AppDelegate.swift buat variabel:

var enableAllOrientation = false

Jadi, letakkan juga func ini:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

Jadi, di setiap kelas di proyek Anda, Anda dapat mengatur var ini di viewWillAppear:

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

Jika Anda perlu membuat pilihan berdasarkan jenis perangkat Anda dapat melakukan ini:

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }

penjelasan yang sangat bagus
Mihir Oza

11

Pertama-tama - ini adalah ide yang buruk, secara umum, ada yang salah dengan arsitektur aplikasi Anda, tetapi sh..t happens, jika demikian, Anda dapat mencoba membuat sesuatu seperti di bawah ini:

final class OrientationController {

    static private (set) var allowedOrientation:UIInterfaceOrientationMask = [.all]

    // MARK: - Public

    class func lockOrientation(_ orientationIdiom: UIInterfaceOrientationMask) {
        OrientationController.allowedOrientation = [orientationIdiom]
    }

    class func forceLockOrientation(_ orientation: UIInterfaceOrientation) {
        var mask:UIInterfaceOrientationMask = []
        switch orientation {
            case .unknown:
                mask = [.all]
            case .portrait:
                mask = [.portrait]
            case .portraitUpsideDown:
                mask = [.portraitUpsideDown]
            case .landscapeLeft:
                mask = [.landscapeLeft]
            case .landscapeRight:
                mask = [.landscapeRight]
        }

        OrientationController.lockOrientation(mask)

        UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
    }
}

Dari pada AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // do stuff
    OrientationController.lockOrientation(.portrait)
    return true
}

// MARK: - Orientation

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return OrientationController.allowedOrientation
}

Dan setiap kali Anda ingin mengubah orientasi lakukan sebagai:

OrientationController.forceLockOrientation(.landscapeRight)

Catatan: Terkadang, perangkat mungkin tidak diperbarui dari panggilan tersebut, jadi Anda mungkin perlu melakukan sebagai berikut

OrientationController.forceLockOrientation(.portrait)
OrientationController.forceLockOrientation(.landscapeRight)

Itu saja


9

Ini harus bekerja dari iOS 6 ke atas, tetapi saya hanya mengujinya di iOS 8. Subkelas UINavigationControllerdan mengganti metode berikut:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return NO;
}

Atau tanyakan pengontrol tampilan yang terlihat

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.visibleViewController.preferredInterfaceOrientationForPresentation;
}

- (BOOL)shouldAutorotate {
    return self.visibleViewController.shouldAutorotate;
}

dan terapkan metode di sana.


Saya baru saja menguji ini pada aplikasi saya di Xcode 8.2.1 yang menjalankan iOS 10.0 dan berfungsi. Menu gim saya adalah layar pertama dan itu tidak berputar; semua tampilan lain diputar. Sempurna! Berikan satu. Saya hanya membutuhkan fungsi 'preferredInterfaceOrientationForPresentation' yang diberikan oleh Mojo66.
Philip Borges

9

Ini adalah umpan balik ke komentar dalam jawaban Sid Shah , mengenai cara menonaktifkan animasi menggunakan:

[UIView setAnimationsEnabled:enabled];

Kode:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    [UIView setAnimationsEnabled:NO];

    // Stackoverflow #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}

Bagaimana saya bisa menggunakan ini untuk Potret.
Muju

6

Jika Anda menggunakan navigationViewController Anda harus membuat superclass Anda sendiri untuk ini dan menimpa:

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

ini akan menonaktifkan rotasi di SecondViewController tetapi jika Anda mendorong SecondViewController Anda ketika perangkat Anda pada orientasi potret maka Anda SecondViewController akan muncul dalam mode potret.

Asumsikan bahwa Anda menggunakan storyboard. Anda harus membuat segmen manual ( Cara ) dan dalam metode "onClick" Anda:

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

Ini akan memaksa orientasi lanskap sebelum fitur superclass Anda menonaktifkan autorotate.


6

Pada Xcode 8metode dikonversi ke properti, jadi berikut ini berfungsi dengan Swift:

override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override public var shouldAutorotate: Bool {
    return true
}

Apakah ini mengunci orientasi?
bnussey

1
@Bnussey Saya ingin mencegah rotasi otomatis dan selalu pada portraitmode tidak peduli apa orientasi di iPad, dengan shouldAutorotatemengembalikan benar saya mencapai itu.
Ali Momen Sani

4

Saya telah mencoba banyak solusi, tetapi yang berhasil adalah sebagai berikut:

Tidak perlu mengedit info.plistdi ios 8 dan 9.

- (BOOL) shouldAutorotate {
    return NO;
}   

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}

Kemungkinan orientasi dari Dokumentasi Apple :

UIInterfaceOrientationUnknown

Orientasi perangkat tidak dapat ditentukan.

UIInterfaceOrientationPortrait

Perangkat dalam mode potret, dengan perangkat dipegang tegak dan tombol home di bagian bawah.

UIInterfaceOrientationPortraitUpsideDown

Perangkat dalam mode potret tetapi terbalik, dengan perangkat dipegang tegak dan tombol home di atas.

UIInterfaceOrientationLandscapeLeft

Perangkat dalam mode lansekap, dengan perangkat dipegang tegak dan tombol beranda di sisi kiri.

UIInterfaceOrientationLandscapeRight

Perangkat dalam mode lansekap, dengan perangkat dipegang tegak dan tombol beranda di sisi kanan.


3

Kombinasi jawaban Sids dan Koreys bekerja untuk saya.

Memperluas Pengendali Navigasi:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

Kemudian nonaktifkan rotasi pada Tampilan tunggal

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

Dan berputar ke orientasi yang sesuai sebelum segue

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}

Apakah Anda tahu jika ini dapat membantu masalah saya di mana pengontrol tampilan yang ditampilkan dalam lansekap untuk satu detik sebelum diputar ke potret seperti seharusnya selalu? pertanyaan ada di sini: stackoverflow.com/questions/30693964/…
dwinnbrown

3

Solusi teratas di atas:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

tidak bekerja untuk saya ketika saya menyebutnya di viewDidAppear dari pengontrol tampilan yang disajikan. Namun itu berhasil ketika saya memanggilnya di preparForSegue di controller tampilan presentasi.

(Maaf, reputasi poin tidak cukup untuk mengomentari solusi itu, jadi saya harus menambahkannya seperti ini)


Saya mendapatkan ini berfungsi tetapi ketika pergi dari pengontrol tampilan lansekap ke pengontrol tampilan potret, pengontrol tampilan yang harus ditampilkan dalam potret secara singkat ditampilkan dalam lanskap sebelum diputar sendiri. kalau ada yang tahu bagaimana membantu pertanyaan saya ada di sini: stackoverflow.com/questions/30693964/…
dwinnbrown

@dwinnbrown di viewDidAppear tampilan controller sudah terlihat. Mungkin coba dari viewDidLoad saja?
Crashalot

@ Crashalot sekarang saya sudah memperbaikinya. Silakan lihat jawaban yang saya tandai sebagai benar.
dwinnbrown

@dwinbrown tautan ke pertanyaan Anda sudah mati. memperbarui? Terima kasih!
Crashalot

@ Crashalot komunitas menghapusnya tetapi saya telah memilih untuk membatalkan penghapusan. Saya akan segera memberi tahu Anda
dwinnbrown

3

[iOS9 +] Jika ada yang menyeret ke sini karena tidak ada solusi di atas yang berfungsi, dan jika Anda menyajikan tampilan yang ingin Anda ubah orientasi dengan segue, Anda mungkin ingin memeriksanya.

Periksa jenis presentasi segue Anda. Milik saya 'atas konteks saat ini'. Ketika saya mengubahnya ke Layar Penuh, itu berhasil.

Terima kasih kepada @GabLeRoux, saya menemukan solusi ini.

  • Perubahan ini hanya berfungsi jika dikombinasikan dengan solusi di atas.

2

Persyaratan saya adalah

  1. mengunci semua tampilan dalam mode potret
  2. gunakan AVPlayerViewControlleruntuk memutar video

Saat video diputar, jika berupa lanskap maka izinkan layar untuk memutar lanskap ke kanan dan kiri lanskap. Jika itu potret maka kunci tampilan dalam mode potret saja.

Pertama, tentukan supportedInterfaceOrientationsForWindowdiAppDelegate.swift

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

Kedua, di pengontrol tampilan utama Anda, tentukan fungsi berikut

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

override func shouldAutorotate() -> Bool {
    return false
}

Kemudian, Anda perlu subkelas AVPlayerViewController

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

Timpa ketiga fungsi ini di MyPlayerViewController.swift

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

Karena pengguna mungkin memutar lansekap perangkat ke kiri atau lansiran kanan, kita perlu mengatur rotasi otomatis menjadi true

override func shouldAutorotate() -> Bool {
    return true
}

Akhirnya, buat MyPlayerViewControllerinstance di pengontrol tampilan Anda dan atur nilai ukuran properti.

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

Inisiasi pemain Anda dengan benar videoUrl, lalu tetapkan pemain Anda ke playerViewController. Selamat coding!


2
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIViewController attemptRotationToDeviceOrientation];
}

1

Tampaknya masih ada beberapa perdebatan tentang cara terbaik untuk menyelesaikan tugas ini, jadi saya pikir saya akan berbagi pendekatan (bekerja) saya. Tambahkan kode berikut dalam UIViewControllerimplementasi Anda :

- (void) viewWillAppear:(BOOL)animated
{
    [UIViewController attemptRotationToDeviceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}

Untuk contoh ini, Anda juga perlu mengatur orientasi perangkat yang diizinkan ke 'Landscape Left' di pengaturan proyek Anda (atau langsung masuk info.plist ). Ubah saja orientasi spesifik yang ingin Anda paksakan jika Anda menginginkan sesuatu selainLandscapeLeft.

Kuncinya bagi saya adalah attemptRotationToDeviceOrientationpanggilan masuk viewWillAppear- tanpa itu tampilan tidak akan berputar dengan baik tanpa memutar perangkat secara fisik.


Metode usang.
Saqib Omer

1

Berdasarkan jawaban Korey Hinton

Swift 2.2:

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return visibleViewController!.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController!.shouldAutorotate()
    }
}


extension UITabBarController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

Nonaktifkan Rotasi

override func shouldAutorotate() -> Bool {
    return false
}

Kunci ke Orientasi Tertentu

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}

1

Saya mencoba beberapa solusi di sini dan yang penting untuk dipahami adalah pengontrol tampilan akar yang akan menentukan apakah akan diputar atau tidak.

Saya buat berikut tujuan-c proyek github.com/GabLeRoux/RotationLockInTabbedViewChild dengan contoh kerja dariTabbedViewController mana satu tampilan anak diperbolehkan berputar dan pandangan anak lainnya terkunci dalam potret.

Ini tidak sempurna tetapi berfungsi dan ide yang sama harus bekerja untuk jenis tampilan root lainnya seperti NavigationViewController. :)

Tampilan anak mengunci orientasi orang tua


0

Menurut solusi yang ditunjukkan oleh @ sid-sha Anda harus meletakkan semuanya dalam viewDidAppear:metode, jika tidak, Anda tidak akan didRotateFromInterfaceOrientation:dipecat, jadi sesuatu seperti:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}

0

Solusi saya

Di AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if let topController = UIViewController.topMostViewController() {
        if topController is XXViewController {
            return [.Portrait, .LandscapeLeft]
        }
    }
    return [.Portrait]
}

XXViewController adalah ViewController yang ingin Anda dukung mode Lansekap.

Maka solusi Sunny Shah akan bekerja di Anda XXViewControllerpada versi iOS apa pun:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

Ini adalah fungsi utilitas untuk menemukan ViewController paling atas.

extension UIViewController {

    /// Returns the current application's top most view controller.
    public class func topMostViewController() -> UIViewController? {
        let rootViewController = UIApplication.sharedApplication().windows.first?.rootViewController
        return self.topMostViewControllerOfViewController(rootViewController)
    }



    /// Returns the top most view controller from given view controller's stack.
    class func topMostViewControllerOfViewController(viewController: UIViewController?) -> UIViewController? {
        // UITabBarController
        if let tabBarController = viewController as? UITabBarController,
           let selectedViewController = tabBarController.selectedViewController {
            return self.topMostViewControllerOfViewController(selectedViewController)
        }

        // UINavigationController
        if let navigationController = viewController as? UINavigationController,
           let visibleViewController = navigationController.visibleViewController {
            return self.topMostViewControllerOfViewController(visibleViewController)
        }

        // presented view controller
        if let presentedViewController = viewController?.presentedViewController {
            return self.topMostViewControllerOfViewController(presentedViewController)
        }

        // child view controller
        for subview in viewController?.view?.subviews ?? [] {
            if let childViewController = subview.nextResponder() as? UIViewController {
                return self.topMostViewControllerOfViewController(childViewController)
            }
        }

        return viewController
    }

}

0

Gunakan ini untuk mengunci orientasi pengontrol tampilan, yang diuji pada iOS 9:

// Kunci orientasi ke kanan lansekap

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}

0

Saya memiliki masalah yang sama dan menghabiskan banyak waktu untuk itu. Jadi sekarang saya punya solusi. Pengaturan aplikasi saya hanya mendukung potret saja. Namun, beberapa layar ke dalam aplikasi saya perlu hanya lanskap. Saya memperbaikinya dengan memiliki variabel isShouldRotate at AppDelegate . Dan fungsi di AppDelegate :

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

Dan akhirnya ketika ViewControllerA membutuhkan kondisi lansekap. Lakukan saja: sebelum push / present ke ViewController, tetapkan isShouldRotate ke true . Jangan lupa ketika pop / abaikan bahwa assign controller isShouldRotate ke false di viewWillDisappear .


0

Bagi saya, VC tingkat atas diperlukan untuk mengimplementasikan orientasi yang ditimpa. Menggunakan VC di tumpukan tidak akan berpengaruh jika VC atas tidak menerapkan.

VC-main
    |
    -> VC 2
        |
        -> VC 3

Hanya VC-Main yang didengarkan, pada dasarnya dalam pengujian saya.


0

Sepertinya bahkan kamu di sini begitu banyak jawaban tidak ada yang cukup untukku. Saya ingin memaksakan orientasi dan kemudian kembali kembali ke orientasi perangkat tetapi [UIViewController attemptRotationToDeviceOrientation];tidak berhasil. Yang juga rumit adalah saya menambahkan shouldAutorotate ke false berdasarkan beberapa jawaban dan tidak bisa mendapatkan efek yang diinginkan untuk memutar kembali dengan benar di semua skenario.

Jadi ini yang saya lakukan:

Sebelum mendorong controller dalam panggilan di init konstruktornya ini:

_userOrientation = UIDevice.currentDevice.orientation;
[UIDevice.currentDevice setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
[self addNotificationCenterObserver:@selector(rotated:)
                               name:UIDeviceOrientationDidChangeNotification];

Jadi saya menyimpan orientasi perangkat terakhir dan mendaftar untuk acara perubahan orientasi. Acara perubahan orientasi sederhana:

- (void)rotated:(NSNotification*)notification {
    _userOrientation = UIDevice.currentDevice.orientation;
}

Dan pada pandangan dissmising saya hanya memaksa kembali ke orientasi yang saya miliki sebagai userOreintation:

- (void)onViewDismissing {
    super.onViewDismissing;
    [UIDevice.currentDevice setValue:@(_userOrientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

Dan ini juga harus ada di sana:

- (BOOL)shouldAutorotate {
    return true;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

Dan juga pengendali navigasi harus mendelegasikan ke shouldAutorotate dan didukungInterfaceOrientations, tetapi kebanyakan orang sudah memiliki saya percaya.

PS: Maaf saya menggunakan beberapa ekstensi dan kelas dasar tetapi nama cukup berarti sehingga konsep dapat dimengerti, akan membuat lebih banyak ekstensi karena itu tidak terlalu cantik sekarang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.