เนื่องจากShouldAutorotateToInterfaceOrientation
เลิกใช้งานแล้วใน iOS 6 และฉันใช้สิ่งนั้นเพื่อบังคับให้มุมมองเฉพาะเป็นแนวตั้งเท่านั้นวิธีที่ถูกต้องในการทำสิ่งนี้ใน iOS 6 คืออะไร? นี่เป็นเพียงพื้นที่เดียวในแอปของฉันมุมมองอื่น ๆ ทั้งหมดสามารถหมุนได้
เนื่องจากShouldAutorotateToInterfaceOrientation
เลิกใช้งานแล้วใน iOS 6 และฉันใช้สิ่งนั้นเพื่อบังคับให้มุมมองเฉพาะเป็นแนวตั้งเท่านั้นวิธีที่ถูกต้องในการทำสิ่งนี้ใน iOS 6 คืออะไร? นี่เป็นเพียงพื้นที่เดียวในแอปของฉันมุมมองอื่น ๆ ทั้งหมดสามารถหมุนได้
คำตอบ:
หากคุณต้องการให้ตัวควบคุมการนำทางทั้งหมดของเราเคารพตัวควบคุมมุมมองด้านบนคุณสามารถใช้หมวดหมู่เพื่อที่คุณจะได้ไม่ต้องผ่านและเปลี่ยนชื่อคลาสมากมาย
@implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
เนื่องจากความคิดเห็นบางส่วนชี้ให้เห็นว่านี่เป็นการแก้ไขปัญหาอย่างรวดเร็ว ทางออกที่ดีกว่าคือ UINavigationController subclass และใส่วิธีการเหล่านี้ไว้ที่นั่น คลาสย่อยยังช่วยในการรองรับ 6 และ 7
วิธีที่ดีที่สุดสำหรับ iOS6 โดยเฉพาะมีการระบุไว้ใน "iOS6 By Tutorials" โดยทีม Ray Wenderlich - http://www.raywenderlich.com/และดีกว่าคลาสย่อยUINavigationController
สำหรับกรณีส่วนใหญ่
ฉันใช้ iOS6 กับสตอรีบอร์ดที่มีUINavigationController
ชุดเป็นตัวควบคุมมุมมองเริ่มต้น
//AppDelegate.m - วิธีนี้ไม่สามารถใช้งานได้กับ iOS6 ล่วงหน้า
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
//MyViewController.m - ส่งคืนทิศทางที่คุณต้องการสนับสนุนสำหรับแต่ละทิศทาง UIViewController
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
คำตอบนี้เกี่ยวข้องกับคำถามที่ถามในความคิดเห็นของโพสต์ของ OP:
ในการบังคับให้มุมมองปรากฏในแนวที่กำหนดให้ใส่สิ่งต่อไปนี้ใน viewWillAppear:
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
มันเป็นการแฮ็กเล็กน้อย แต่สิ่งนี้บังคับUIViewController
ให้นำเสนอในแนวตั้งแม้ว่าตัวควบคุมก่อนหน้าจะเป็นแนวนอนก็ตาม
อัปเดตสำหรับ iOS7
วิธีการข้างต้นเลิกใช้แล้วดังนั้นสำหรับ iOS 7 ให้ใช้สิ่งต่อไปนี้:
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[c.view setBackgroundColor:[UIColor redColor]];
[self.navigationController presentViewController:c animated:NO completion:^{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
}];
}];
}
ที่น่าสนใจในขณะที่เขียนไม่ว่าจะเป็นของขวัญหรือการเลิกจ้างต้องเป็นภาพเคลื่อนไหว หากไม่มีคุณจะได้หน้าจอสีขาว ไม่รู้ว่าทำไมสิ่งนี้ถึงใช้งานได้ แต่มันทำได้! เอฟเฟกต์ภาพจะแตกต่างกันไปขึ้นอยู่กับสิ่งที่เคลื่อนไหว
ดังนั้นฉันจึงพบปัญหาเดียวกันเมื่อแสดงมุมมองโมดอลในแนวตั้งเท่านั้น โดยปกติฉันจะสร้าง a UINavigationController
ตั้งค่าviewController
เป็นrootViewController
แล้วแสดงUINavigationController
เป็นมุมมองโมดอล แต่ด้วย iOS 6 viewController
ตอนนี้จะถาม navigationController สำหรับการวางแนวอินเทอร์เฟซที่รองรับ (ซึ่งโดยค่าเริ่มต้นตอนนี้เป็นทั้งหมดสำหรับ iPad และทุกอย่างยกเว้นสำหรับ iPhone)
วิธีแก้ไข : ฉันต้อง subclass UINavigationController
และแทนที่วิธีการ autorotation ชนิดของง่อย
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
iOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
iOS 6
-(BOOL)shouldAutorotate{
return YES;
}
-(NSInteger)supportedInterfaceOrientations{
// UIInterfaceOrientationMaskLandscape;
// 24
//
// UIInterfaceOrientationMaskLandscapeLeft;
// 16
//
// UIInterfaceOrientationMaskLandscapeRight;
// 8
//
// UIInterfaceOrientationMaskPortrait;
// 2
// return UIInterfaceOrientationMaskPortrait;
// or
return 2;
}
ฉันไม่เห็นด้วยกับคำตอบของ @aprato เนื่องจากวิธีการหมุน UIViewController ได้รับการประกาศเป็นหมวดหมู่เองจึงส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนดหากคุณแทนที่ในหมวดหมู่อื่น ปลอดภัยกว่าที่จะแทนที่พวกเขาในคลาสย่อย UINavigationController (หรือ UITabBarController)
นอกจากนี้สิ่งนี้ไม่ครอบคลุมสถานการณ์ที่คุณผลัก / นำเสนอ / ป๊อปจากมุมมองแนวนอนไปเป็นแนวตั้งเท่านั้นหรือในทางกลับกัน ในการแก้ไขปัญหาที่ยากลำบากนี้ (Apple ไม่เคยกล่าวถึง) คุณควร:
ใน iOS <= 4 และ iOS> = 6:
UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];
ใน iOS 5:
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
สิ่งเหล่านี้จะบังคับให้ UIKit ประเมิน shouldAutorotate, supportedInterfaceOrientations และอื่น ๆ อีกครั้ง
ฉันมีแนวทางที่ดีมากในการผสมhttps://stackoverflow.com/a/13982508/2516436และhttps://stackoverflow.com/a/17578272/2516436
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}
และส่งคืนทิศทางที่คุณต้องการสนับสนุนสำหรับ UIViewController แต่ละตัว
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
ฉันมีแอปสากลที่ค่อนข้างซับซ้อนโดยใช้ UISplitViewController และ UISegmentedController และมีมุมมองบางอย่างที่ต้องนำเสนอในแนวนอนโดยใช้ presentViewController
ไฟล์. ด้วยวิธีการที่แนะนำข้างต้นฉันสามารถทำให้ iPhone ios 5 & 6 ทำงานได้อย่างเป็นที่ยอมรับ แต่ด้วยเหตุผลบางประการ iPad ก็ปฏิเสธที่จะนำเสนอเป็นแนวนอน ในที่สุดฉันก็พบวิธีง่ายๆ (ใช้งานได้หลังจากอ่านและลองผิดลองถูกมาหลายชั่วโมง) ที่ใช้ได้กับทั้งอุปกรณ์และ ios 5 & 6
ขั้นตอนที่ 1) บนคอนโทรลเลอร์ระบุการวางแนวที่ต้องการ (มากหรือน้อยตามที่ระบุไว้ข้างต้น)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSInteger mask = UIInterfaceOrientationMaskLandscape;
return mask;
}
ขั้นตอนที่ 2) สร้างคลาสย่อย UINavigationController อย่างง่ายและใช้วิธีการต่อไปนี้
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
ขั้นตอนที่ 3) นำเสนอ viewController ของคุณ
vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];
หวังว่านี่จะเป็นประโยชน์กับใครบางคน
ไม่น่าเบื่อที่นี่ แต่คุณจะใจดีมากที่จะแบ่งปันคลาสย่อยของคุณหรือไม่? ขอขอบคุณ.
แก้ไข: ในที่สุดฉันก็ทำได้คลาสย่อยก็ตายง่ายที่จะทำ ฉันต้องประกาศnavigationController
ในAppDelegate
as UINavigationControllerSubclass
แทนค่าเริ่มต้นUINavigationController
จากนั้นแก้ไขคลาสย่อยของคุณด้วย:
- (BOOL)shouldAutorotate {
return _shouldRotate;
}
ฉันจึงสามารถตั้งค่ามุมมองที่ต้องการหมุนหรือไม่ก็ได้โดยโทรไปที่ viewDidLoad
_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]
หวังว่าการปรับแต่งนี้จะช่วยผู้อื่นได้เช่นกันขอบคุณสำหรับเคล็ดลับ!
เคล็ดลับ: ใช้ประโยชน์จากไฟล์
- (NSUInteger)supportedInterfaceOrientations
ในตัวควบคุมมุมมองของคุณดังนั้นคุณจะไม่ต้องมีมุมมองแนวตั้งที่ต้องการในแนวนอนหรือในทางกลับกัน
ฉันไม่ได้ทดสอบด้วยตัวเอง แต่เอกสารระบุว่าตอนนี้คุณสามารถแทนที่วิธีการเหล่านั้นได้: supportedInterfaceOrientations
และpreferredInterfaceOrientationForPresentation
.
คุณสามารถบรรลุสิ่งที่คุณต้องการ y การตั้งค่าเฉพาะการวางแนวที่คุณต้องการในวิธีการเหล่านั้น
คำตอบโดยใช้คลาสย่อยหรือหมวดหมู่เพื่อให้ VCs ภายในคลาส UINavigationController และ UITabBarController ทำงานได้ดี การเรียกใช้โมดอลแนวตั้งเท่านั้นจากคอนโทรลเลอร์แถบแนวนอนล้มเหลว หากคุณจำเป็นต้องทำเช่นนี้แล้วใช้เคล็ดลับของการแสดงและซ่อนไม่เคลื่อนไหวมุมมองกิริยา แต่ทำมันในวิธี viewDidAppear มันไม่ได้ผลสำหรับฉันใน viewDidLoad หรือ viewWillAppear
นอกเหนือจากนั้นโซลูชันข้างต้นยังใช้ได้ดี
สำหรับ Monotouch คุณสามารถทำได้ด้วยวิธีนี้:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.LandscapeRight;
}
public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
{
return UIInterfaceOrientation.LandscapeRight;
}
ฉันเห็นคำตอบมากมาย แต่ไม่ได้รับแนวคิดและคำตอบที่เฉพาะเจาะจงเกี่ยวกับการวางแนว แต่เห็นลิงก์เข้าใจการวางแนวและลบการหมุนอย่างแรงสำหรับ ios6
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
ฉันคิดว่ามันช่วยเต็มที่
เพียงไปที่ project.plist จากนั้นเพิ่มการวางแนวอินเตอร์เฟซที่รองรับจากนั้นเพิ่มเฉพาะ Portrait (ปุ่มโฮมด้านล่าง) และ Portrait (ปุ่มโฮมด้านบน)
คุณสามารถเพิ่มหรือลบการวางแนวได้ตามความต้องการของโครงการ
ขอบคุณ
1) ตรวจสอบการตั้งค่าโครงการและ info.plist ของคุณและตรวจสอบให้แน่ใจว่าได้เลือกเฉพาะการวางแนวที่คุณต้องการเท่านั้น
2) เพิ่มวิธีการต่อไปนี้ในตัวควบคุมมุมมองด้านบนสุดของคุณ (ตัวควบคุมการนำทาง / ตัวควบคุมแถบแถบ)
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
3) เพิ่มวิธีการต่อไปนี้ให้กับตัวแทนแอปของคุณ
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
ใส่ไว้ในไฟล์. m ของแต่ละไฟล์ที่ViewController
คุณไม่ต้องการหมุน:
- (NSUInteger)supportedInterfaceOrientations
{
//return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
return UIInterfaceOrientationMaskPortrait;
}
ดูที่นี่สำหรับข้อมูลเพิ่มเติม