Orientasi yang didukung tidak memiliki orientasi yang sama dengan aplikasi, dan shouldAutorotate mengembalikan YES '

92

Aplikasi saya (iPad; iOS 6) adalah aplikasi khusus lanskap, tetapi ketika saya mencoba menggunakan UIPopoverController untuk menampilkan perpustakaan foto, kesalahan ini muncul: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.Saya telah mencoba mengubah banyak kode tetapi saya tidak berhasil.

Destiny Dawn
sumber
1
Anda harus menerima jawaban. ada banyak orang yang membutuhkan bantuan dan untuk orang lain yang memiliki masalah yang sama, akan terbantu jika Anda menandai jawaban yang benar untuk masalah Anda!
sikat51
1
Tidak! tidak ada solusi yang berfungsi di iOS 7 :( (headbang)
AsifHabib
Jawaban terbaik di sini stackoverflow.com/questions/20468335/…
Damien Romito

Jawaban:

94

Di IOS6 Anda telah mendukung orientasi antarmuka di tiga tempat:

  1. The .plist (atau Layar Ringkasan Target)
  2. UIApplicationDelegate Anda
  3. UIViewController yang sedang ditampilkan

Jika Anda mendapatkan kesalahan ini, kemungkinan besar karena tampilan yang Anda muat di UIPopover Anda hanya mendukung mode potret. Ini bisa disebabkan oleh Game Center, iAd, atau pandangan Anda sendiri.

Jika ini adalah tampilan Anda sendiri, Anda dapat memperbaikinya dengan mengganti supportInterfaceOrientations yang didukung di UIViewController Anda:

- (NSUInteger) supportedInterfaceOrientations
{
     //Because your app is only landscape, your view controller for the view in your
     // popover needs to support only landscape
     return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

Jika ini bukan tampilan Anda sendiri (seperti GameCenter di iPhone), Anda perlu memastikan .plist Anda mendukung mode potret. Anda juga perlu memastikan UIApplicationDelegate Anda mendukung tampilan yang ditampilkan dalam mode potret. Anda dapat melakukan ini dengan mengedit .plist Anda dan kemudian menimpaInterfaceOrientation yang didukung di UIApplicationDelegate Anda:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Snickers
sumber
3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightsama UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightdenganUIInterfaceOrientationMaskLandscape
Valerii Pavlov
4
Atau cukup gunakan UIInterfaceOrientationMaskAll.
Mark Wang
Sempurna. Meskipun popover "hanya potret" akan bekerja dalam lanskap, popover tidak dapat menampilkan pengontrol tampilan hanya lanskap secara sederhana.
Neal Ehardt
Tidak! Solusi tidak bekerja pada iOS 7 :(. Stackoverflow.com/questions/23005351/...
AsifHabib
Bekerja pada iOS 8. Padahal, harus menambahkan dukungan potret ke plist. Terima kasih.
Yaroslav
65

Setelah menghabiskan banyak waktu mencari cara untuk menghindari subclass dan menambahkan banyak kode, inilah solusi kode satu baris saya.

Buat kategori baru UIImagePickerController dan tambahkan

-(BOOL)shouldAutorotate{
    return NO;
}

Itu semua orang!

Dr. Luiji
sumber
1
Berhasil untuk saya juga, belum sepenuhnya diuji tetapi tampaknya berhasil sejauh ini.
migs647
2
Ini sepertinya solusi terbaik.
Julian
2
Bekerja! Ini bagus, dan sangat membantu saya dalam keadaan darurat. Terima kasih Dr Luiji !!
brack
1
Bagus. Bekerja untuk saya di iOS 6. Anda juga dapat membuat ini dapat dikonfigurasi dalam kategori untuk fleksibilitas penuh.
Jared Egan
3
tidak berfungsi di iOS7, metode kategori bahkan tidak dipanggil (meskipun termasuk dalam pch)
Peter Lapisu
43

Ada kasus lain pesan kesalahan ini mungkin muncul. Saya mencari berjam-jam sampai saya menemukan masalahnya. Utas ini sangat membantu setelah membacanya beberapa kali.

Jika pengontrol tampilan utama Anda diputar ke orientasi lanskap dan Anda menjalankan pengontrol sub tampilan kustom yang harus ditampilkan dalam orientasi potret, pesan kesalahan ini dapat terjadi jika kode Anda terlihat seperti ini:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

Perangkap di sini adalah intellisense xcode yang disarankan "UIInterfaceOrientationPortrait" dan saya tidak peduli tentang itu. Sekilas ini sepertinya benar.

Nama topeng yang tepat

UIInterfaceOrientationMaskPortrait

Waspadai infix kecil "Mask" , jika tidak subview Anda akan berakhir dengan pengecualian dan pesan kesalahan yang disebutkan di atas.

Enum baru sedikit bergeser. Enum lama mengembalikan nilai yang tidak valid!

(di UIApplication.h Anda bisa melihat deklarasi baru: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )

Solusinya adalah:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

    // ATTENTION! Only return orientation MASK values
    // return UIInterfaceOrientationPortrait;

    return UIInterfaceOrientationMaskPortrait;
} 

Digunakan dengan cepat

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
JackPearse
sumber
5
terjadi pada saya karena alasan yang sama
ChenXin
Saya berharap apel hanya akan membuat jenis kembalian UIInterfaceOrientationMask sehingga sedikit lebih jelas apa yang perlu dikembalikan.
LightningStryk
Jawaban Jackpearse sepertinya benar. Namun saat melihat info.plist, ada UISupportedInterfaceOrientations dengan UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight. Tidak ada MASK di sini
onmyway133
1
@onmyway: Itu benar, nilai-nilai plist tidak berubah. Pada versi iOS sebelumnya, Apple menggunakan nilai topeng "non" di dalam kode. Ini adalah beberapa barang warisan. Saya berasumsi bahwa apel sedikit menggeser nilai-nilai plist secara internal sekarang.
JackPearse
Aplikasi saya dulu berfungsi tanpa masalah mogok ini pada simulator iPad Xcode 6.2. Dan itu macet setelah saya meningkatkan ke Xcode 6.3 beberapa hari yang lalu. Sekarang solusi ini memperbaiki masalah saya. Terima kasih banyak :-)
Golden Thumb
22

Saya mengalami masalah serupa saat menampilkan alat pilih gambar dalam aplikasi lanskap saja. Seperti yang disarankan oleh Dr. Luiji, saya menambahkan kategori berikut di awal pengontrol saya.

// This category (i.e. class extension) is a workaround to get the
// Image PickerController to appear in landscape mode.
@interface UIImagePickerController(Nonrotating)
- (BOOL)shouldAutorotate;
@end

@implementation UIImagePickerController(Nonrotating)

- (BOOL)shouldAutorotate {
  return NO;
}
@end

Paling mudah menambahkan baris ini tepat sebelum @implementation dari file ViewController .m Anda.

Trausti Kristjansson
sumber
Saya memiliki aplikasi hanya potret! dan saya ingin menampilkan Kamera dalam mode Lansekap. ada solusi ?????
AsifHabib
Trausti tidak berhasil? Saya memiliki masalah yang sama dan saya mencoba kode Anda tetapi masih muncul pengecualian yang sama *** Menghentikan aplikasi karena pengecualian yang tidak tertangkap 'UIApplicationInvalidInterfaceOrientation', alasan: 'Orientasi yang didukung tidak memiliki orientasi yang sama dengan aplikasi, dan shouldAutorotate mengembalikan YA ..... ... saya juga meletakkan breakpoint pada metode kategori UIimagePickerView shouldAutorotate mencapai sana dan tidak mengembalikan tetapi tetap memberikan pengecualian ini .... Aplikasi saya hanya aplikasi Lansekap ... tolong bantu saya
Vishal16
Juga berfungsi untuk memaksa SKStoreProductViewController untuk ditampilkan dalam mode potret saat seluruh aplikasi dalam lanskap di iOS 8. Berterima kasih.
Yaroslav
11

Saya menemukan pesan kesalahan yang sama dalam kode saya. Saya menemukan ini, itu bug seperti yang dilaporkan oleh Apple:

https://devforums.apple.com/message/731764#731764

Solusinya adalah memperbaikinya di AppDelegate. Saya menerapkannya dan berhasil untuk saya!

Robby
sumber
Ngomong-ngomong, saya awalnya menemukan ini di: stackoverflow.com/questions/12522491/…
Robby
Ini adalah jawaban yang benar, langsung dari Apple, dan kemudian saya hanya harus mengikuti instruksi yang sama tetapi melakukannya di Swift untuk aplikasi yang menargetkan iOS 8. Semuanya bekerja dengan baik. AppDelegate set yang didukungInterfaceOrientationsForWindow ke Landscape dan Portrait, setiap file swift individu menetapkan override fungsi yang didukungInterfaceOrientations ke Landscape saja sehingga tampilan tidak akan berputar, tetapi ketika tampilan potret (dalam kasus saya SKStoreProductViewController) perlu dimuat, itu berfungsi!
RanLearns
Astaga, ada begitu banyak solusi yang disarankan, dan yang ini sejauh ini tidak memiliki poin tertinggi, tetapi memang benar. Diuji di iOS 10 dan 9. Tidak ada lagi yang berhasil.
Demian Turner
6

Saya memiliki masalah yang sama dan jawaban ini https://stackoverflow.com/a/12523916 bekerja untuk saya. Bertanya-tanya apakah ada solusi yang lebih elegan.

Kode saya:

UIImagePickerController  *imagePickerController = [[NonRotatingUIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

UIPopoverController  *popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];    

[popoverVC presentPopoverFromRect:frame   // did you forget to call this method?
                           inView:view
         permittedArrowDirections:UIPopoverArrowDirectionAny
                         animated:YES];
penyair
sumber
Saya mencoba melakukan itu tetapi ketika saya mengklik tombol untuk memanggil kode tetapi tidak ada yang ditampilkan, saya juga mencoba menambahkan @interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @endkode tetapi kode saya tidak mendeteksi NonRotatingUIImagePickerController.
Destiny Dawn
1
Tidak apa-apa, Ini mendeteksi NonRotatingUIImagePickerController sekarang tetapi tidak ada yang ditampilkan ... @poetowen
Destiny Dawn
4

iOS 8 - Anda dapat menggunakan UIModalPresentationPopover tanpa peretasan apa pun untuk ditampilkan di popover. Tidak ideal tapi lebih baik daripada tidak sama sekali.

imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.view;
imagePicker.popoverPresentationController.sourceRect = ((UIButton *)sender).frame;

Sunting: mungkin coba UIModalPresentationStyles yang berbeda - mungkin lebih banyak yang akan bekerja dalam lanskap.

derbs
sumber
3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.
Suhail Bhat
sumber
2

Opsi lain yang menyelesaikan masalah saya adalah membuat subclass UIImagePickerController dan mengganti metode di bawah ini

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Gunakan ini sebagai ganti UIImagePickerController dan semuanya berfungsi dengan baik.

EquiAvia Tech
sumber
1

Membuat kategori sangat membantu untuk memperbaiki bug ini. Dan jangan lupa untuk mengimpor kategori yang Anda buat. Ini akan menambahkan metode yang hilang ke UIImagePickerController dan di iOS 6 itu akan membatasinya untuk bekerja di Portrait hanya sebagai dokumentasi menyatakan btw.

Solusi lain mungkin berhasil. Tetapi dengan SDK untuk iOS 8.x yang dikompilasi untuk diterapkan pada iOS 6.1 ini tampaknya cara untuk pergi.

File .h:

#import <UIKit/UIKit.h>

@interface UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;

@end

File .m:

#import "UIImagePickerController+iOS6FIX.h"

@implementation UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate {
    return NO;
}

- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

@end
Helge Staedtler
sumber
1

Cepat 3

let imagePicker = UIImagePickerController()

imagePicker.modalPresentationStyle = .popover
imagePicker.popoverPresentationController?.sourceView = sender // you can also pass any view 

present(imagePicker, animated: true)
zombie
sumber
0

Saya mengalami masalah mogok ini saat mengonversi UIInterfaceOrientationPortraitmenjadi UIInterfaceOrientationMaskPortraitsecara implisit sebagai nilai kembali.

Lebih banyak latar belakang kode UIPageViewControllerDelegate, hanya FYI untuk Anda semua.

 -(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
    # return UIInterfaceOrientationPortrait;    # wrong
    return UIInterfaceOrientationMaskPortrait;  # correct
}
Itachi
sumber
0

Saya baru saja menyelesaikan masalah untuk Swift 4.x

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    configureVideoOrientation()
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: nil, completion: { [weak self] _ in
        self?.configureVideoOrientation()
    })
}

private func configureVideoOrientation() {
    guard let previewLayer = self.previewLayer, let connection = previewLayer.connection else { return }
    if connection.isVideoOrientationSupported {
        let orientation = UIApplication.shared.statusBarOrientation
        switch (orientation) {
        case .portrait:
            previewLayer.connection?.videoOrientation = .portrait
        case .landscapeRight:
            previewLayer.connection?.videoOrientation = .landscapeRight
        case .landscapeLeft:
            previewLayer.connection?.videoOrientation = .landscapeLeft
        case .portraitUpsideDown:
            previewLayer.connection?.videoOrientation = .portraitUpsideDown
        default:
            previewLayer.connection?.videoOrientation = .portrait
        }

        previewLayer.frame = self.view.bounds
    }
}

Terima kasih teman-teman atas jawaban Anda juga. Saya baru saja memotong kode yang berfungsi dan hanya memfaktorkan ulangnya.

atereshkov
sumber
0

Swift 4 dan yang lebih baru dengan asumsi seluruh aplikasi dalam lanskap dan Anda perlu menampilkan satu pengontrol dalam mode potret. Dalam pengontrol tampilan yang harus potret tambahkan yang berikut ini:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
Gal Kosong
sumber