ايفون:في الوضع الأفقي فقط، بعد addSubview لأول مرة، لا يتم تدوير UITableViewController بشكل صحيح

StackOverflow https://stackoverflow.com/questions/1632117

  •  06-07-2019
  •  | 
  •  

سؤال

يتوفر مشروع Xcode توضيحي بسيط لهذا الغرض على جيثب.

في UIWindow الخاص بي، عندما أقوم بإضافة UITableView الثاني (واللاحق) كعروض فرعية، فإنها لا تدور بشكل صحيح، وبالتالي تظهر بشكل جانبي.يتم اختبار هذا فقط في جهاز المحاكاة.إليك رمزًا صغيرًا لك:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    ShellTVC* viewA = [[ShellTVC alloc] initWithTitle:@"View A"];
    ShellTVC* viewB = [[ShellTVC alloc] initWithTitle:@"View B"];

    // The first subview added will rotate to landscape correctly. 
    // Any subsequent subview added will not.

    // You may try this by various commentings and rearranging of these two statements.

    [window addSubview:[viewA tableView]];
    [window addSubview:[viewB tableView]];

    [window makeKeyAndVisible];
}

يظهر viewB بشكل جانبي.قم بالتعليق على addSubview لـ viewB، وسيظهر viewA بشكل صحيح.افعل ذلك مع viewA فقط، وسيظهر viewB بشكل صحيح.

أنا لا أقوم بإنشاء UITableViewControllers عبر NIBs، على الرغم من أن UIWindow كذلك.

في حال كنت تتساءل، فإن ShellTVC هو UITableViewController، ويقوم بتنفيذ هذه الطريقة:

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

لقد قمت أيضًا بتعيين UIInterfaceOrientation في ملف plist على UIInterfaceOrientationLandscapeLeft.

ربما ذات صلة - ولم تتم الإجابة عليها - أسئلة SO هنا و هنا.

هل كانت مفيدة؟

المحلول

أعتقد أنني وجدت طريقة - ربما الطريقة الصحيحة - للقيام بذلك.

  1. قم بإنشاء فئة فرعية "رئيسية" UIViewController، والتي تنفذ mustAutorotate...، وأضفها كطريقة العرض الوحيدة في نافذتك.
  2. للتبديل بين viewA أو viewB، استخدم مجموعةdismodalViewControllerAnimated:& PresentModalViewController:animated:على وحدة تحكم العرض الرئيسية هذه.

إليك بعض التعليمات البرمجية:

// this doesn't really do much but implement shouldAutorotate...
@interface MasterViewController : UIViewController
@end

@implementation MasterViewController
- (BOOL) shouldAutorotateToInterfaceOrientation(UIInterfaceOrientation)interfaceOrientation {
     return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
@end

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
    MasterViewController* masterVC;
    UIViewController* activeTVC;
    UIViewController* onDeckTVC;
}
@end

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    UIViewController* masterVC = [[MasterViewController alloc] init];        
    activeTVC = [[ShellTVC alloc] initWithTitle:@"View A"];
    onDeckTVC = [[ShellTVC alloc] initWithTitle:@"View B"];
    [window addSubview:masterView.view];
    [window makeKeyAndVisible];
    [masterVC presentModalViewController:activeTVC animated:NO];
}

// you would call this to toggle between "View A" and "View B"
- (void)toggleTVC {
    UITableViewController *hold = activeTVC;
    activeTVC = onDeckTVC;
    onDeckTVC = hold;
    [masterVC dismissModalViewControllerAnimated:NO];   
    [masterVC presentModalViewController:activeTVC animated:NO];
}

لماذا يعمل هذا؟

  1. تتدفق جميع تغييرات الاتجاه من خلال وحدات تحكم العرض، وليس طرق العرض.

  2. بقدر ما أستطيع أن أقول، فإن العرض الأول أو العرض الفرعي الذي تضيفه إلى نافذتك يحصل على بعض الصلصة الخاصة.إذا كان هذا العرض يحتوي على وحدة تحكم في العرض، فستكتشفه النافذة.

أي أنه بالنسبة للعرض الفرعي الأول فقط، يمكنك التفكير في هذا الكود:

[window addSubview:masterVC.view];

مثل القيام بشيء مثل هذا (ليس طريقة حقيقية!):

[window addSubview:masterVC.view withViewController:masterVC];

لا أفهم في هذا الأمر أكثر من ذلك.أجد حقيقة أنني أستطيع القيام بذلك مع العرض الفرعي الأول، ولكن ليس مع الآخرين، أمر محير للغاية.مزيد من المعلومات موضع ترحيب، واسمحوا لي أن أعرف إذا كان هذا ساعدك أم لا.

نصائح أخرى

وعلى ما يبدو إذا قمت بإضافة عرض كطفل وجهات النظر سوف تكون استدارة بشكل صحيح. هذا ليس حلا رائعا لمشروعي، ولكن يبدو أنه قد يكون الحل الوحيد.

ومما يؤسف له subviews بك ويطلب فقط حول ما التوجهات التي تدعمها عندما يحدث تغيير في التوجه.

وهكذا أنا في نهاية المطاف تحديد الاتجاه قبل أن يدفع تحكم النظرة الجديدة إلى كومة لو كنت أعلم أنه يتغير:

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 

نعم، هذا هو دعوة غير معتمد.

ويمكنك استخدام الكائن UIApplication لفرض التوجه جهاز معين.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];

نعم، أعتقد أن لديك على حل هذه القضية من خلال وجود XIB متعددة. أتذكر رؤية هذا الحل من خلال أحد الكتب التي قرأتها في الماضي. إن لم يكن لديك لعب مع الترجمة وموقف الكائن في عرض ... أفضل أن يكون XIB منفصل.

وهذا يجب أن تعمل.

- (void)viewDidLoad {
    if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) || 
        ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) 

    {
        self.view.frame = CGRectMake(0, 0, 1024, 748);

    } else {
        self.view.frame = CGRectMake(0, 0, 768, 1004);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top