การวางแนวที่รองรับไม่มีการวางแนวทั่วไปกับแอปพลิเคชันและ shouldAutorotate กำลังส่งคืน YES


94

แอพของฉัน (iPad; iOS 6) เป็นแอปพลิเคชั่นแนวนอนเท่านั้น แต่เมื่อฉันลองใช้ UIPopoverController เพื่อแสดงไลบรารีรูปภาพมันทำให้เกิดข้อผิดพลาดนี้: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.ฉันได้ลองเปลี่ยนรหัสหลายรอบ แต่ฉันไม่มีโชค


1
คุณควรยอมรับคำตอบ มีคนจำนวนมากขอความช่วยเหลือและสำหรับคนอื่น ๆ ที่มีปัญหาเดียวกันก็ช่วยได้เมื่อคุณทำเครื่องหมายคำตอบที่ถูกต้องสำหรับปัญหาของคุณ
brush51

1
ไม่! ไม่มีวิธีแก้ปัญหาบน iOS 7 :( (headbang)
AsifHabib

คำตอบที่ดีที่สุดที่นี่ stackoverflow.com/questions/20468335/…
Damien Romito

คำตอบ:


95

ใน IOS6 คุณได้รองรับการวางแนวอินเทอร์เฟซในสามตำแหน่ง:

  1. .plist (หรือหน้าจอสรุปเป้าหมาย)
  2. UIApplicationDelegate ของคุณ
  3. UIViewController ที่กำลังแสดง

หากคุณได้รับข้อผิดพลาดนี้เป็นไปได้มากว่ามุมมองที่คุณกำลังโหลดใน UIPopover ของคุณรองรับเฉพาะโหมดแนวตั้งเท่านั้น ซึ่งอาจเกิดจาก Game Center, iAd หรือมุมมองของคุณเอง

หากเป็นมุมมองของคุณเองคุณสามารถแก้ไขได้โดยการลบล้าง supportedInterfaceOrientations บน UIViewController ของคุณ:

- (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;
}

หากไม่ใช่มุมมองของคุณเอง (เช่น GameCenter บน iPhone) คุณต้องแน่ใจว่า. plist ของคุณรองรับโหมดแนวตั้ง คุณต้องแน่ใจว่า UIApplicationDelegate ของคุณรองรับมุมมองที่แสดงในโหมดแนวตั้ง คุณสามารถทำได้โดยการแก้ไข. plist ของคุณจากนั้นแทนที่การสนับสนุนอินเทอร์เฟซโอริเอนเตชันบน UIApplicationDelegate ของคุณ:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightเท่ากับUIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightเท่ากับUIInterfaceOrientationMaskLandscape
Valerii Pavlov

4
หรือใช้ UIInterfaceOrientationMaskAll
Mark Wang

สมบูรณ์แบบ. แม้ว่าป็อปโอเวอร์ "แนวตั้งเท่านั้น" จะทำงานในแนวนอน แต่ก็ไม่สามารถนำเสนอตัวควบคุมมุมมองแนวนอนเท่านั้น
Neal Ehardt

ไม่! โซลูชันไม่ทำงานบน iOS 7 :(. stackoverflow.com/questions/23005351/…
AsifHabib

ทำงานบน iOS 8 แม้ว่าจะต้องเพิ่มการสนับสนุนแนวตั้งเพื่อ plist ขอขอบคุณ.
Yaroslav

65

หลังจากใช้เวลาค้นหาวิธีหลีกเลี่ยงการคลาสย่อยและเพิ่มโค้ดจำนวนมากนี่คือโซลูชันโค้ดบรรทัดเดียวของฉัน

สร้างหมวดหมู่ UIImagePickerController ใหม่และเพิ่ม

-(BOOL)shouldAutorotate{
    return NO;
}

นั่นคือคนทั้งหมด!


1
ทำงานให้ฉันเช่นกันยังไม่ได้ทดสอบอย่างเต็มที่ แต่ดูเหมือนจะทำตามเคล็ดลับจนถึงตอนนี้
migs647

2
นี่ดูเหมือนจะเป็นทางออกที่ดีที่สุด
Julian

2
ได้ผล! นี่ยอดเยี่ยมมากและมันช่วยฉันได้จริงๆ ขอบคุณ Dr Luiji !!
วงเล็บ

1
ดี. ใช้ได้กับฉันบน iOS 6 คุณสามารถกำหนดค่านี้ได้ในหมวดหมู่เพื่อความยืดหยุ่นอย่างเต็มที่
Jared Egan

3
ไม่ทำงานใน iOS7 วิธีการหมวดหมู่ไม่ได้ถูกเรียก (แม้ว่าจะรวมอยู่ใน pch)
Peter Lapisu

43

มีอีกกรณีหนึ่งข้อความแสดงข้อผิดพลาดนี้อาจปรากฏขึ้น ฉันค้นหาอยู่หลายชั่วโมงจนพบปัญหา กระทู้นี้มีประโยชน์มากหลังจากอ่านไปสองสามครั้ง

หากตัวควบคุมมุมมองหลักของคุณหมุนเป็นแนวนอนและคุณเรียกใช้ตัวควบคุมมุมมองย่อยแบบกำหนดเองซึ่งควรแสดงในแนวตั้งข้อความแสดงข้อผิดพลาดนี้อาจเกิดขึ้นได้เมื่อโค้ดของคุณมีลักษณะดังนี้:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

กับดักที่นี่คือ Intellisense ของ xcode ที่แนะนำ "UIInterfaceOrientationPortrait" และฉันไม่สนใจมัน ในแวบแรกดูเหมือนว่าจะถูกต้อง

ชื่อหน้ากากที่เหมาะสม

UIInterfaceOrientationMaskPortrait

โปรดระวัง"Mask" ที่มีขนาดเล็กมิฉะนั้นมุมมองย่อยของคุณจะจบลงด้วยข้อยกเว้นและข้อความแสดงข้อผิดพลาดดังกล่าวข้างต้น

enums ใหม่มีการเปลี่ยนแปลงเล็กน้อย enums เก่าส่งคืนค่าที่ไม่ถูกต้อง!

(ใน UIApplication.h คุณสามารถดูการประกาศใหม่: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )

วิธีแก้ปัญหาคือ:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

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

    return UIInterfaceOrientationMaskPortrait;
} 

ในการใช้งานที่รวดเร็ว

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

5
เกิดขึ้นกับฉันด้วยเหตุผลเดียวกัน
ChenXin

ฉันหวังว่าแอปเปิ้ลจะสร้าง UIInterfaceOrientationMask ประเภทการส่งคืนเพื่อให้ชัดเจนขึ้นเล็กน้อยว่าต้องส่งคืนอะไร
LightningStryk

คำตอบของ Jackpearse ถูกต้อง แต่เมื่อดูใน info.plist จะมี UISupportedInterfaceOrientations พร้อม UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight ไม่มีหน้ากากที่นี่
onmyway133

1
@onmyway: นั่นเป็นความจริงค่า plist ไม่ได้เปลี่ยนแปลง ใน iOS เวอร์ชันก่อน Apple ใช้ค่ามาสก์ "non" ภายในโค้ด นี่คือสิ่งที่เป็นมรดกตกทอด ฉันคิดว่าแอปเปิลกำลังขยับค่า plist ภายในตอนนี้
JackPearse

แอพของฉันเคยใช้งานได้โดยไม่มีปัญหาการหยุดทำงานบนเครื่องจำลอง iPad ของ Xcode 6.2 และมันล้มเหลวหลังจากที่ฉันอัปเกรดเป็น Xcode 6.3 เมื่อไม่กี่วันที่ผ่านมา ตอนนี้วิธีนี้แก้ไขปัญหาของฉันได้ ขอบคุณมาก :-)
Golden Thumb

22

ฉันมีปัญหาคล้ายกันนี้เมื่อนำเสนอตัวเลือกรูปภาพในแอพแนวนอนเท่านั้น ตามคำแนะนำของดร. Luiji ฉันได้เพิ่มหมวดหมู่ต่อไปนี้ที่จุดเริ่มต้นของตัวควบคุมของฉัน

// 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

ง่ายที่สุดในการเพิ่มบรรทัดเหล่านี้ก่อนการติดตั้ง @implementation ของไฟล์ ViewController .m ของคุณ


ฉันมีแอพแนวตั้งเท่านั้น! และฉันต้องการแสดงกล้องถ่ายรูปในโหมดแนวนอน วิธีแก้ปัญหาใด ๆ ?????
AsifHabib

Trausti ไม่ทำงาน? ฉันมีปัญหาเดียวกันและฉันลองใช้รหัสของคุณ แต่ยังคงมีข้อยกเว้นเหมือนเดิม *** การยุติแอปเนื่องจากข้อยกเว้น "UIApplicationInvalidInterfaceOrientation" ที่ไม่ถูกจับเหตุผล: 'การวางแนวที่รองรับไม่มีการวางแนวทั่วไปกับแอปพลิเคชันและ shouldAutorotate กำลังส่งคืนใช่ ..... ... ฉันยังใส่เบรกพอยต์ในเมธอดประเภท UIimagePickerView ด้วย shouldAutorotate ไปถึงที่นั่นและไม่ส่งคืน แต่ยังคงให้ข้อยกเว้นนี้ .... แอพของฉันเป็นแอพแนวนอนเท่านั้น ... โปรดช่วยฉันด้วย
Vishal16

ยังทำงานเพื่อบังคับให้ SKStoreProductViewController นำเสนอในแนวตั้งเมื่อทั้งแอปเป็นแนวนอนใน iOS 8 ขอบคุณ
Yaroslav

11

ฉันพบข้อความแสดงข้อผิดพลาดเดียวกันในรหัสของฉัน ฉันพบว่านี่เป็นข้อผิดพลาดตามที่ Apple รายงาน:

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

วิธีแก้ปัญหาของเขาคือการแก้ไขใน AppDelegate ฉันใช้มันและมันได้ผลสำหรับฉัน!


โดยวิธีเดิมฉันพบสิ่งนี้ที่: stackoverflow.com/questions/12522491/…
Robby

นี่เป็นคำตอบที่ถูกต้องโดยตรงจาก Apple จากนั้นฉันก็ต้องทำตามคำแนะนำเดียวกัน แต่ทำใน Swift สำหรับแอปที่กำหนดเป้าหมายเป็น iOS 8 ทุกอย่างใช้งานได้ดี ชุด AppDelegate ที่รองรับ InterfaceOrientationsForWindow ทั้งแนวนอนและแนวตั้งแต่ละไฟล์ที่รวดเร็วแต่ละไฟล์จะตั้งค่าการแทนที่ func ที่รองรับ InterfaceOrientations เป็นแนวนอนเท่านั้นดังนั้นมุมมองจะไม่หมุน แต่เมื่อต้องโหลดมุมมองแนวตั้ง (ในกรณีของฉัน SKStoreProductViewController) ก็ใช้งานได้!
RanLearns

Jeez มีวิธีแก้ปัญหาที่แนะนำมากมายและวิธีนี้ไม่มีคะแนนสูงสุด แต่เป็นวิธีที่ถูกต้อง ทดสอบแล้วบน iOS 10 และ 9 ไม่มีอะไรใช้ได้
Demian Turner

6

ฉันมีปัญหาเดียวกันและคำตอบนี้https://stackoverflow.com/a/12523916ใช้ได้กับฉัน สงสัยว่ามีวิธีแก้ปัญหาที่หรูหรากว่านี้หรือไม่

รหัสของฉัน:

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];

ฉันพยายามทำเช่นนั้น แต่เมื่อฉันคลิกปุ่มเพื่อเรียกรหัส แต่ไม่มีอะไรปรากฏขึ้นฉันก็ลองเพิ่ม@interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @endรหัส แต่รหัสของฉันไม่พบ NonRotatingUIImagePickerController
Destiny Dawn

1
ไม่เป็นไรมันตรวจจับ NonRotatingUIImagePickerController ตอนนี้ แต่ไม่มีอะไรแสดง ... @poetowen
Destiny Dawn

4

iOS 8 - คุณสามารถใช้ UIModalPresentationPopover ได้โดยไม่ต้องแฮ็กใด ๆ เพื่อแสดงในป๊อปโอเวอร์ ไม่เหมาะ แต่ดีกว่าไม่มีอะไรเลย

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

แก้ไข: อาจลองใช้ UIModalPresentationStyles ที่แตกต่างกัน - อาจจะมากกว่านี้ในแนวนอน



2

อีกทางเลือกหนึ่งที่แก้ไขปัญหาของฉันคือการสร้างคลาสย่อยของ UIImagePickerController และเพื่อแทนที่วิธีการด้านล่าง

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

ใช้สิ่งนี้แทน UIImagePickerController และทุกอย่างก็ใช้ได้ดี


1

การสร้างหมวดหมู่มีประโยชน์มากในการแก้ไขข้อบกพร่องนี้ และอย่าลืมนำเข้าหมวดหมู่ที่คุณสร้างขึ้น สิ่งนี้จะเพิ่มเมธอดที่ขาดหายไปให้กับ UIImagePickerController และบน iOS 6 จะ จำกัด ให้ทำงานในแนวตั้งเท่านั้นตามที่เอกสารระบุ btw

วิธีแก้ปัญหาอื่น ๆ อาจใช้งานได้ แต่ด้วย SDK สำหรับ iOS 8.x ที่คอมไพล์เพื่อปรับใช้บน iOS 6.1 ดูเหมือนว่าจะไปได้

ไฟล์. h:

#import <UIKit/UIKit.h>

@interface UIImagePickerController (iOS6FIX)

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

@end

ไฟล์. m:

#import "UIImagePickerController+iOS6FIX.h"

@implementation UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate {
    return NO;
}

- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

@end

1

สวิฟต์ 3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)

0

ฉันพบปัญหาข้อขัดข้องนี้เมื่อแปลงUIInterfaceOrientationPortraitเป็นUIInterfaceOrientationMaskPortraitโดยปริยายเป็นค่าตอบแทน

พื้นหลังโค้ดเพิ่มเติมUIPageViewControllerDelegateเพียง FYI สำหรับคุณทุกคน

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

0

ฉันเพิ่งแก้ไขปัญหาสำหรับ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
    }
}

ขอบคุณสำหรับคำตอบของคุณ ฉันเพิ่งตัดโค้ดที่ใช้งานได้และปรับโครงสร้างใหม่


0

Swift 4 ขึ้นไปโดยสมมติว่าทั้งแอปอยู่ในแนวนอนและคุณต้องนำเสนอคอนโทรลเลอร์ตัวเดียวในแนวตั้ง ในตัวควบคุมมุมมองที่ต้องเป็นแนวตั้งให้เพิ่มสิ่งต่อไปนี้:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.