มีเอกสารวิธีตั้งค่าการวางแนว iPhone หรือไม่?


94

ฉันมีแอพที่ฉันต้องการรองรับการหมุนอุปกรณ์ในบางมุมมอง แต่แอพอื่นไม่สมเหตุสมผลในโหมดแนวนอนดังนั้นเมื่อฉันเปลี่ยนมุมมองออกไปฉันต้องการบังคับให้ตั้งค่าการหมุนเป็นแนวตั้ง

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

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];

มีเอกสารวิธีบังคับทิศทางหรือไม่?

อัปเดต:ฉันคิดว่าฉันจะให้ตัวอย่างเนื่องจากฉันไม่ได้มองหา shouldAutorotateToInterfaceOrientation เนื่องจากฉันได้ดำเนินการไปแล้ว

ฉันต้องการให้แอปของฉันรองรับแนวนอนและแนวตั้งในมุมมอง 1 แต่เฉพาะแนวตั้งในมุมมอง 2 ฉันได้ติดตั้ง shouldAutorotateToInterfaceOrientation สำหรับมุมมองทั้งหมดแล้ว แต่ถ้าผู้ใช้อยู่ในโหมดแนวนอนในมุมมอง 1 จากนั้นเปลี่ยนเป็นมุมมอง 2 ฉันต้องการบังคับ โทรศัพท์เพื่อหมุนกลับไปที่แนวตั้ง


11
ฉันได้ยื่นข้อบกพร่องเกี่ยวกับเรื่องนี้โดยแนะนำให้ Apple เปิดเผย API ข้างต้นหรือให้เกียรติ YES ไม่มีการส่งคืนจากวิธีการ shouldRotate เมื่อการดูโหลดครั้งแรกไม่ใช่เฉพาะเมื่อโทรศัพท์หมุน
rustyshelf

2
ฉันได้ยื่นข้อบกพร่องเพื่อขอให้มีการเปิดเผย
setOrientation

1
[[UIDevice currentDevice] setOrientation: UIInterfaceOrientationPortrait]; วิธีนี้เลิกใช้แล้วและไม่มีอีกแล้ว
Hikmat Khan

คำตอบ:


6

นี่ไม่ใช่ปัญหาใน iPhone 3.1.2 SDK รุ่นหลังอีกต่อไป ตอนนี้ดูเหมือนว่าจะเป็นไปตามการวางแนวที่ร้องขอของมุมมองที่ถูกผลักกลับไปที่สแต็ก นั่นหมายความว่าคุณจะต้องตรวจจับ iPhone OS เวอร์ชันเก่าและใช้ setOrientation เฉพาะเมื่อก่อนรุ่นล่าสุด

ไม่ชัดเจนว่าการวิเคราะห์แบบคงที่ของ Apple จะเข้าใจว่าคุณกำลังดำเนินการตามข้อ จำกัด SDK ที่เก่ากว่าหรือไม่ ฉันได้รับแจ้งจาก Apple เป็นการส่วนตัวให้ลบการโทรเมธอดในการอัปเดตครั้งต่อไปของฉันดังนั้นฉันจึงยังไม่แน่ใจว่าการแฮ็กสำหรับอุปกรณ์รุ่นเก่าจะผ่านกระบวนการอนุมัติ


ไม่ใช่กรณีของ iPhone Simulator 3.3.2 มันยังใช้ไม่ได้
เป็ด

4
@user คุณขอการวางแนวอย่างไรเมื่อคุณกดดูบนสแต็ก
progrmr

4
คุณสามารถใช้การวิเคราะห์แบบคงที่ของ Apple ได้ ฉันใช้รหัสที่ไม่มีเอกสารได้สำเร็จโดยใช้ performSelector และอาศัยพลังที่ยอดเยี่ยมของ Obj-C
Kenneth Ballenegger

@KennethBallenegger ฉันจำได้ว่าอ่านหลักเกณฑ์และ / หรือข้อตกลงว่าการซ่อนสิ่งต่างๆเช่นนี้อาจทำให้แอปของคุณถูกลบและอาจถึงขั้นลบบัญชีของคุณ ฉันจะไม่เสี่ยงแค่ใช้ API ที่ไม่มีเอกสาร
Ivan Vučica

101

สิ่งนี้เกิดขึ้นนานแล้ว แต่ในกรณีที่มีใครเข้ามาโดยที่ไม่ได้ใช้ตัวควบคุมการนำทางและ / หรือไม่ต้องการใช้วิธีการที่ไม่มีเอกสาร:

UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
[c release];

เพียงพอที่จะนำเสนอและปิดตัวควบคุมมุมมองวานิลลา

เห็นได้ชัดว่าคุณยังคงต้องยืนยันหรือปฏิเสธการวางแนวในการแทนที่ shouldAutorotateToInterfaceOrientation แต่สิ่งนี้จะทำให้ shouldAutorotate ... ถูกเรียกอีกครั้งโดยระบบ


1
น่ากลัวหนึ่งนี้ไม่ได้ทำเครื่องหมายเป็นคำตอบที่ถูกต้องของการโพสต์นี้ แต่แก้ไขได้เพียงครึ่งหนึ่งของปัญหาของฉันstackoverflow.com/questions/5030315 เคล็ดลับการวางแนวตั้งในแนวตั้งของมุมมองแบบจำลอง 'กองกำลัง' คุณจะรู้วิธีบังคับแนวนอนหรือไม่?
epologee

5
ฮะฮะ !! นี่มันโง่เกินไป! แต่ได้ผล! - แน่นอน! : D
hfossli

น่ากลัวดิ้นรนกับเรื่องนี้มานาน ขอบคุณ! mate
Rahul Choudhary

3
ดูเหมือนว่าจะใช้ได้กับทั้ง iOS5 และ iOS6: [self presentViewController: [UIViewController ใหม่] ภาพเคลื่อนไหว: ไม่เสร็จสมบูรณ์: ^ {[self dischargeViewControllerAnimate: NO complete: nil]; }];
Inferis

1
ดูเหมือนว่าจะใช้งานได้บน iOS 7 และ iOS 8 แต่มีหน้าจอสีดำที่เห็นได้ชัดซึ่งจะกะพริบในมุมมอง (iOS 8 เป็นหลัก)
levigroker

16

หากคุณต้องการบังคับให้หมุนจากแนวตั้งเป็นแนวนอนนี่คือรหัส โปรดทราบว่าคุณต้องปรับจุดศูนย์กลางของมุมมองของคุณ ฉันสังเกตเห็นว่าของฉันไม่ได้วางมุมมองในสถานที่ที่เหมาะสม มิฉะนั้นจะทำงานได้อย่างสมบูรณ์ ขอบคุณสำหรับทิป.

if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){

        [UIView beginAnimations:@"View Flip" context:nil];
        [UIView setAnimationDuration:0.5f];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
        self.view.bounds = CGRectMake(0.0f, 0.0f, 480.0f, 320.0f);
        self.view.center = CGPointMake(160.0f, 240.0f);

        [UIView commitAnimations];
}

จะใช้งานได้หรือไม่ถ้าฉันเพิ่ม UIAlertView ฉันพยายามCGAffineTransformMakeRotationหมุนมุมมอง แต่ UIAlertView ยังคงเป็นไปตามการวางแนวแถบสถานะเช่น -degreeToRadian (มุม)? คุณได้รับสิ่งนี้หรือไม่?
NeverHopeless

วิธีที่ง่ายที่สุดที่จะทำเช่นนี้กับUIAlertViewคือการตั้งค่าการควบคุมมุมมองของคุณเป็นตัวแทน alertView และจากนั้นในการ: คุณจะดำเนินการหมุนขึ้นอยู่กับปัจจุบัน- (void) didPresentAlertView:(UIAlertView *) alertView [UIApplication sharedApplication].statusBarOrientationหากคุณไม่เคลื่อนไหวก็ไม่ควรดูแปลกเกินไป
Michael Gaylord

16

จากสิ่งที่ฉันบอกได้setOrientation:วิธีนี้ไม่ได้ผล (หรืออาจใช้ไม่ได้อีกต่อไป) นี่คือสิ่งที่ฉันทำเพื่อทำสิ่งนี้:

ขั้นแรกวางคำจำกัดความนี้ไว้ที่ด้านบนสุดของไฟล์ใต้ #imports ของคุณ:

#define degreesToRadian(x) (M_PI * (x) / 180.0)

จากนั้นในviewWillAppear:วิธีการ

[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];     
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {  
    self.view.transform = CGAffineTransformIdentity;
    self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
    self.view.bounds = CGRectMake(0.0, 0.0, 480, 320);
}

หากคุณต้องการให้สิ่งนั้นเป็นภาพเคลื่อนไหวคุณสามารถรวมสิ่งทั้งหมดไว้ในบล็อกแอนิเมชั่นดังนี้:

[UIView beginAnimations:@"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];     
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {  
    self.view.transform = CGAffineTransformIdentity;
    self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
    self.view.bounds = CGRectMake(0.0, 0.0, 480, 320);
}
[UIView commitAnimations];

จากนั้นในตัวควบคุมโหมดแนวตั้งคุณสามารถย้อนกลับได้ - ตรวจสอบว่าขณะนี้อยู่ในแนวนอนหรือไม่และหากเป็นเช่นนั้นให้หมุนกลับเป็นแนวตั้ง


1
แทนที่จะเป็น self.view คุณควรหมุน self.window.view สิ่งนี้มีประโยชน์หากคุณมี UITabBar หรือตัวควบคุมอื่น ๆ อยู่เหนือมุมมองของคุณ
Borut Tomazin

7

ฉันประสบปัญหาที่ฉันมีUIViewControllerบนหน้าจอUINavigationControllerในแนวนอน อย่างไรก็ตามเมื่อตัวควบคุมมุมมองถัดไปถูกผลักในโฟลว์ฉันต้องการให้อุปกรณ์กลับสู่การวางแนวตั้ง

สิ่งที่ฉันสังเกตเห็นคือshouldAutorotateToInterfaceOrientation:เมธอดไม่ถูกเรียกเมื่อตัวควบคุมมุมมองใหม่ถูกผลักลงบนสแต็ก แต่จะถูกเรียกเมื่อตัวควบคุมมุมมองถูกดึงออกมาจากสแต็

การใช้ประโยชน์จากสิ่งนี้ฉันกำลังใช้ข้อมูลโค้ดนี้ในหนึ่งในแอปของฉัน:

- (void)selectHostingAtIndex:(int)hostingIndex {

    self.transitioning = YES;

    UIViewController *garbageController = [[[UIViewController alloc] init] autorelease];
    [self.navigationController pushViewController:garbageController animated:NO];
    [self.navigationController popViewControllerAnimated:NO];

    BBHostingController *hostingController = [[BBHostingController alloc] init];
    hostingController.hosting = [self.hostings objectAtIndex:hostingIndex];
    [self.navigationController pushViewController:hostingController animated:YES];
    [hostingController release];

    self.transitioning = NO;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    if (self.transitioning)
        return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
    else
        return YES;
}

โดยพื้นฐานแล้วการสร้างตัวควบคุมมุมมองที่ว่างเปล่าผลักมันลงในสแต็กและเปิดออกทันทีเป็นไปได้ที่จะทำให้อินเทอร์เฟซเปลี่ยนกลับเป็นตำแหน่งแนวตั้ง เมื่อเปิดตัวควบคุมแล้วฉันก็แค่กดตัวควบคุมที่ฉันตั้งใจจะผลักในตอนแรก สายตามันดูดี - ผู้ใช้ไม่เคยมองเห็นตัวควบคุมมุมมองที่ว่างเปล่าโดยพลการ


สวัสดีฉันเพิ่งใช้วิธีการของคุณในการบังคับ VC ในแนวนอนที่ถูกต้องก่อนที่จะผลักดัน แต่ฉันพบว่ามันใช้ได้เฉพาะเมื่อบังคับให้วางแนวตั้ง (หากมุมมองปัจจุบันเป็นแนวตั้งและคุณต้องการบังคับให้เป็นแนวนอนถัดไปก็จะชนะ ไม่ควรเรียก shouldAutorotateToInterfaceOrientation: เมื่อ popping) คุณพบวิธีแก้ปัญหาเพื่อบังคับให้มุมมองไปที่แนวนอนหรือไม่?
Rafael Nobre

น่าสนใจ - ฉันไม่มีปัญหานี้ขออภัย ฉันจะลองเล่นตามลำดับการผลักและป๊อปมีโอกาสที่ดีที่คุณจะได้อะไรบางอย่าง
Andrew Vilcsak

7

มีวิธีง่ายๆในการบังคับให้ iPhone ไปยังทิศทางที่จำเป็นโดยใช้โปรแกรม - โดยใช้คำตอบที่ให้ไว้แล้วสองคำโดยkdbdallas , Josh :

//will rotate status bar
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];


//will re-rotate view according to statusbar
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
[c release];

ใช้งานได้เหมือนมีเสน่ห์ :)

แก้ไข:

สำหรับ iOS 6 ฉันต้องการเพิ่มฟังก์ชั่นนี้: (ทำงานบน modal viewcontroller)

- (NSUInteger)supportedInterfaceOrientations
{
    return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
}

สำหรับฉันมันไม่ได้ผลเหมือนเสน่ห์: แถบนำทางและแถบเครื่องมือจะหดตัวลงจนเท่ากับความสูงที่จะมีในมุมมองแนวนอน วิธีการลบและเพิ่มมุมมองด้านบนสุดใหม่จะรักษาความสูงที่ถูกต้อง แต่ก็มีข้อเสียเช่นกัน: แถบนำทางของฉันเลื่อนลงเล็กน้อย (ราวกับว่าเปิดใช้งานแถบเทอร์มินัล)
AlexWien

มันใช้งานได้ในตอนท้ายของฉันทั้งบนตัวควบคุมมุมมองแบบโมดอลและแบบพุช แต่เฉพาะบน iOS 5 :(
Guntis Treulands

ใช่ฉันใช้งานได้ใน ios5 ด้วย ตอนนี้ใน ios6 ความสูงของแถบนำทางจะลดลงเมื่อปิดตัวควบคุมมุมมองแนวนอนแบบโมดอล
AlexWien

7

ฉันขุดและขุดหาทางออกที่ดีสำหรับเรื่องนี้ พบบล็อกโพสต์นี้ที่ใช้เคล็ดลับ: ลบมุมมองด้านนอกสุดของคุณออกจากคีย์UIWindowและเพิ่มอีกครั้งจากนั้นระบบจะสอบถามshouldAutorotateToInterfaceOrientation:วิธีการจาก viewcontrollers ของคุณอีกครั้งโดยบังคับให้ใช้การวางแนวที่ถูกต้อง ดูมัน: iphone บังคับให้ uiview reorientate


วิธีนี้ได้ผลดีที่สุดสำหรับฉัน ที่สำคัญการแก้ไขซึ่งนำเสนอ modalViewController ที่ว่างเปล่าทำให้เกิดภาพเคลื่อนไหวที่ไม่ถูกต้องในการผลัก viewcontrollers ไปยังสแตก วิธีการ UIWindow นี้ไม่ประสบปัญหาเดียวกัน
Rik Smith-Unna

5

คำตอบของ Josh ใช้ได้ผลดีสำหรับฉัน

อย่างไรก็ตามฉันชอบโพสต์การแจ้งเตือน"การวางแนวเปลี่ยนไปโปรดอัปเดต UI" เมื่อผู้ควบคุมมุมมองได้รับการแจ้งเตือนนี้จะเรียกใช้shouldAutorotateToInterfaceOrientation:ซึ่งช่วยให้คุณสามารถกำหนดทิศทางใดก็ได้โดยส่งกลับYESสำหรับการวางแนวที่คุณต้องการ

[[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];

ปัญหาเดียวคือสิ่งนี้บังคับให้มีการวางแนวใหม่โดยไม่มีภาพเคลื่อนไหว คุณจะต้องตัดเส้นนี้ระหว่างbeginAnimations:และcommitAnimationsเพื่อให้เกิดการเปลี่ยนแปลงที่ราบรื่น

หวังว่าจะช่วยได้


3

FWIW นี่คือการใช้งานการตั้งค่าการวางแนวด้วยตนเองของฉัน (ไปที่ตัวควบคุมมุมมองรูทของแอปของคุณ natch):

-(void)rotateInterfaceToOrientation:(UIDeviceOrientation)orientation{

    CGRect bounds = [[ UIScreen mainScreen ] bounds ];
    CGAffineTransform t;
    CGFloat r = 0;
    switch ( orientation ) {
        case UIDeviceOrientationLandscapeRight:
            r = -(M_PI / 2);
            break;
        case UIDeviceOrientationLandscapeLeft:
            r  = M_PI / 2;
            break;
    }
    if( r != 0 ){
        CGSize sz = bounds.size;
        bounds.size.width = sz.height;
        bounds.size.height = sz.width;
    }
    t = CGAffineTransformMakeRotation( r );

    UIApplication *application = [ UIApplication sharedApplication ];

    [ UIView beginAnimations:@"InterfaceOrientation" context: nil ];
    [ UIView setAnimationDuration: [ application statusBarOrientationAnimationDuration ] ];
    self.view.transform = t;
    self.view.bounds = bounds;
    [ UIView commitAnimations ];

    [ application setStatusBarOrientation: orientation animated: YES ];     
}

ควบคู่ไปกับUINavigationControllerDelegateวิธีการต่อไปนี้(สมมติว่าคุณใช้ a UINavigationController):

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    // rotate interface, if we need to
    UIDeviceOrientation orientation = [[ UIDevice currentDevice ] orientation ];
    BOOL bViewControllerDoesSupportCurrentOrientation = [ viewController shouldAutorotateToInterfaceOrientation: orientation ];
    if( !bViewControllerDoesSupportCurrentOrientation ){
        [ self rotateInterfaceToOrientation: UIDeviceOrientationPortrait ];
    }
}

ที่ดูแลการหมุนมุมมองรูทตามว่าขาเข้าUIViewControllerรองรับการวางแนวอุปกรณ์ปัจจุบันหรือไม่ สุดท้ายคุณจะต้องเชื่อมrotateInterfaceToOrientationต่อกับการเปลี่ยนแปลงการวางแนวอุปกรณ์จริงเพื่อเลียนแบบการทำงานของ iOS มาตรฐาน เพิ่มตัวจัดการเหตุการณ์นี้ไปยังตัวควบคุมมุมมองรูทเดียวกัน:

-(void)onUIDeviceOrientationDidChangeNotification:(NSNotification*)notification{
    UIViewController *tvc = self.rootNavigationController.topViewController;
    UIDeviceOrientation orientation = [[ UIDevice currentDevice ] orientation ];
    // only switch if we need to (seem to get multiple notifications on device)
    if( orientation != [[ UIApplication sharedApplication ] statusBarOrientation ] ){
        if( [ tvc shouldAutorotateToInterfaceOrientation: orientation ] ){
            [ self rotateInterfaceToOrientation: orientation ];
        }
    }
}

สุดท้ายลงทะเบียนเพื่อรับการUIDeviceOrientationDidChangeNotificationแจ้งเตือนในinitหรือloadviewดังนี้:

[[ NSNotificationCenter defaultCenter ] addObserver: self
                                           selector: @selector(onUIDeviceOrientationDidChangeNotification:)
                                               name: UIDeviceOrientationDidChangeNotification
                                             object: nil ];
[[ UIDevice currentDevice ] beginGeneratingDeviceOrientationNotifications ];

นี่เป็นคำตอบเดียวในหน้านี้ที่ฉันสามารถปรับให้เข้ากับรหัสตัวควบคุมการนำทางได้สำเร็จ ปัญหาเล็กน้อยอย่างหนึ่งคือแถบนำทางที่หมุนไม่ได้เปลี่ยนความสูงระหว่างแนวตั้งและแนวนอนเหมือนที่จะหมุนผ่านกลไกปกติ
Dan Dyer

@ DanDyer คุณได้แก้ไขปัญหาเกี่ยวกับความสูงของแถบนำทางผิดหรือไม่? (โดยเฉพาะใน ios6 ความสูงผิด)
AlexWien

@AlexWien ในที่สุดฉันก็สามารถโน้มน้าวลูกค้าได้ว่าเราไม่ควรทำแบบนี้ สำหรับ iOS 6 คุณอาจต้องทำบางอย่างด้วยshouldAutorotateวิธีการใหม่(ดูstackoverflow.com/a/12586002/5171 )
Dan Dyer

@DanDyer แก้ไขเมื่อวานนี้การซ่อนและแสดงการนำทางและ statusBar อย่างง่าย ๆ ใน ViewDidAppear แก้ไขได้ตอนนี้ใช้งานได้ทั้งหมด (SDK ios6, เป้าหมาย ios5) ฉันต้องทดสอบใหม่ด้วย ios6 เป้าหมาย
AlexWien

2

สิ่งนี้ใช้ได้กับฉัน (ขอบคุณ Henry Cooke):

จุดมุ่งหมายสำหรับฉันคือจัดการกับการเปลี่ยนแปลงแนวนอนเท่านั้น

วิธีการเริ่มต้น:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(orientationChanged:)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:nil];

- (void)orientationChanged:(NSNotification *)notification {    
    //[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    CGRect bounds = [[ UIScreen mainScreen ] bounds ];
    CGAffineTransform t;
    CGFloat r = 0;
    switch ( orientation ) {
        case UIDeviceOrientationLandscapeRight:
            r = 0;
            NSLog(@"Right");
            break;
        case UIDeviceOrientationLandscapeLeft:
            r  = M_PI;
            NSLog(@"Left");
            break;
        default:return;
    }

    t = CGAffineTransformMakeRotation( r );

    UIApplication *application = [ UIApplication sharedApplication ];
    [ UIView beginAnimations:@"InterfaceOrientation" context: nil ];
    [ UIView setAnimationDuration: [ application statusBarOrientationAnimationDuration ] ];
    self.view.transform = t;
    self.view.bounds = bounds;
    [ UIView commitAnimations ];

    [ application setStatusBarOrientation: orientation animated: YES ];
}

1

ฉันมีแอพที่ฉันต้องการรองรับการหมุนอุปกรณ์ในบางมุมมอง แต่แอพอื่นไม่สมเหตุสมผลในโหมดแนวนอนดังนั้นเมื่อฉันเปลี่ยนมุมมองออกไปฉันต้องการบังคับให้ตั้งค่าการหมุนเป็นแนวตั้ง

ฉันรู้ว่าตอนนี้โพสต์ต้นฉบับข้างต้นในหัวข้อนี้เก่ามากแล้ว แต่ฉันมีปัญหาคล้าย ๆ กันนั่นคือ หน้าจอทั้งหมดในแอพของฉันเป็นแนวตั้งเท่านั้นยกเว้นหน้าจอเดียวซึ่งผู้ใช้สามารถหมุนได้ระหว่างแนวนอนและแนวตั้ง

สิ่งนี้ตรงไปตรงมาพอสมควร แต่เช่นเดียวกับโพสต์อื่น ๆ ฉันต้องการให้แอปกลับไปเป็นแนวตั้งโดยอัตโนมัติโดยไม่คำนึงถึงการวางแนวอุปกรณ์ปัจจุบันเมื่อกลับไปที่หน้าจอก่อนหน้า

วิธีแก้ปัญหาที่ฉันใช้คือการซ่อนแถบนำทางในขณะที่อยู่ในโหมดแนวนอนซึ่งหมายความว่าผู้ใช้สามารถกลับไปที่หน้าจอก่อนหน้าได้ในแนวตั้งเท่านั้น ดังนั้นหน้าจออื่น ๆ ทั้งหมดจะต้องเป็นแนวตั้งเท่านั้น

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)pInterfaceOrientation {
    BOOL lHideNavBar = self.interfaceOrientation == UIInterfaceOrientationPortrait ? NO : YES;
    [self.navigationController setNavigationBarHidden:lHideNavBar animated:YES];
}

สิ่งนี้ยังมีประโยชน์เพิ่มเติมสำหรับแอพของฉันด้วยเนื่องจากมีพื้นที่หน้าจอมากขึ้นในโหมดแนวนอน สิ่งนี้มีประโยชน์เนื่องจากหน้าจอดังกล่าวใช้เพื่อแสดงไฟล์ PDF

หวังว่านี่จะช่วยได้


1

ฉันแก้ไขสิ่งนี้ได้ค่อนข้างง่ายในที่สุด ฉันลองทุกคำแนะนำข้างต้นแล้ว แต่ก็ยังสั้นดังนั้นนี่คือวิธีแก้ปัญหาของฉัน:

ใน ViewController ที่ต้องอยู่ในแนวนอน (ซ้ายหรือขวา) ฉันรับฟังการเปลี่ยนแปลงทิศทาง:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didRotate:)
                                             name:UIDeviceOrientationDidChangeNotification object:nil];

จากนั้นใน didRotate:

- (void) didRotate:(NSNotification *)notification
{   if (orientationa == UIDeviceOrientationPortrait) 
    {
        if (hasRotated == NO) 
        {
            NSLog(@"Rotating to portait");
            hasRotated = YES;
            [UIView beginAnimations: @"" context:nil];
            [UIView setAnimationDuration: 0];
            self.view.transform = CGAffineTransformIdentity;
            self.view.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-90));
            self.view.bounds = CGRectMake(0.0f, 0.0f, 480.0f, 320.0f);
            self.view.frame = CGRectMake(0.0f, 0.0f, 480.0f, 320.0f);
            [UIView commitAnimations];

    }
}
else if (UIDeviceOrientationIsLandscape( orientationa))
{
    if (hasRotated) 
    {
        NSLog(@"Rotating to lands");
        hasRotated = NO;
        [UIView beginAnimations: @"" context:nil];
        [UIView setAnimationDuration: 0];
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0));
        self.view.bounds = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
        self.view.frame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
        [UIView commitAnimations];

    }
}

โปรดทราบว่า Super View / Subviews ใด ๆ ที่ใช้การปรับขนาดอัตโนมัติเนื่องจาก view.bounds / frame กำลังถูกรีเซ็ตอย่างชัดเจน ...

ข้อแม้เดียวของวิธีนี้ในการรักษามุมมองแนวนอนคือการสลับภาพเคลื่อนไหวโดยธรรมชาติระหว่างการวางแนวที่จะต้องเกิดขึ้นเมื่อมันจะดีกว่าถ้าดูเหมือนว่าจะไม่มีการเปลี่ยนแปลง


1

โซลูชัน iOS 6:

[[[self window] rootViewController] presentViewController:[[UIViewController alloc] init] animated:NO completion:^{
    [[[self window] rootViewController] dismissViewControllerAnimated:NO completion:nil];
}];

รหัสที่แน่นอนขึ้นอยู่กับแต่ละแอปและตำแหน่งที่คุณวางไว้ (ฉันใช้ใน AppDelegate ของฉัน) แทนที่[[self window] rootViewController]ด้วยสิ่งที่คุณใช้ ฉันใช้ไฟล์UITabBarController.


0

ฉันพบวิธีแก้ปัญหาและเขียนบางอย่างเป็นภาษาฝรั่งเศส (แต่รหัสเป็นภาษาอังกฤษ) ที่นี่

วิธีคือการเพิ่มคอนโทรลเลอร์ในมุมมองหน้าต่าง (ตัวควบคุมต้องมีการใช้งานที่ดีของฟังก์ชั่น shouldRotate .... )


-3

หากคุณใช้ UIViewControllers มีวิธีนี้:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

กลับNOสำหรับตัวควบคุมมุมมองที่มีมุมมองที่คุณไม่ต้องการหมุน

ข้อมูลเพิ่มเติมที่นี่


1
ที่หยุดการหมุนสิ่งที่ฉันกำลังมองหาคือบังคับให้หมุนกลับเป็นแนวตั้งหากผู้ใช้อยู่ในแนวนอน ฉันได้เพิ่มตัวอย่างด้านบนเพื่อบอกว่าฉันหมายถึงอะไรดีกว่า
Dave Verwer

-3

ฉันไม่คิดว่าสิ่งนี้จะทำได้ในขณะทำงานแม้ว่าคุณจะสามารถใช้การแปลง 90 องศากับ UI ของคุณได้


เป็นไปได้ด้วยรหัสที่ฉันโพสต์ในตอนแรกคุณไม่มีทางรู้ว่าเมื่อใดที่อาจหยุดทำงาน;)
Dave Verwer

-3

นี่คือสิ่งที่ฉันใช้ (คุณได้รับคำเตือนในการคอมไพล์ แต่ใช้ได้ทั้งในเครื่องจำลองและ iPhone)

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];

ฉันพบว่าสิ่งนี้เพียงพอที่จะทำให้มันทำงานใน 4.1 ได้เช่นกัน อย่างไรก็ตามเนื่องจากแถบสถานะของฉันถูกตั้งค่าเป็นซ่อนฉันจึงได้รับช่องว่าง 20pixel ที่ด้านบน :(
Anthony Main

setOrientation เป็น API ส่วนตัวและแอปที่ใช้มันถูกปฏิเสธ
เดียว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.