iPhone: только в альбомной ориентации после первого добавления addSubview UITableViewController не вращается должным образом - PullRequest
4 голосов
/ 27 октября 2009

Минимальный иллюстративный проект Xcode для этого доступен на github .

В моем 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 через NIB, хотя UIWindow есть.

Если вам интересно, ShellTVC - это UITableViewController и реализует этот метод:

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

Кроме того, я установил для UIInterfaceOrientation в файле plist значение UIInterfaceOrientationLandscapeLeft.

Вероятно, связанные - и без ответа - ТАК вопросы здесь и здесь .

Ответы [ 6 ]

8 голосов
/ 11 апреля 2010

Думаю, я нашел способ - возможно, правильный - сделать это.

  1. Создайте «основной» подкласс UIViewController, который реализует shouldAutorotate ..., и добавьте его как единственный вид в вашем окне.
  2. Для переключения между viewA или viewB используйте комбинацию dismissModalViewControllerAnimated: & 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];

Я не понимаю больше об этом, чем это. Я нахожу тот факт, что я могу сделать это с первым подпредставлением, но не с другими, в высшей степени озадачивает. Приветствуется больше информации, и, пожалуйста, дайте мне знать, помогло ли это вам или нет.

1 голос
/ 10 апреля 2010

Очевидно, что если вы добавите viewB как дочерний элемент viewA, он будет правильно повернут. Это не лучшее решение для моего проекта, но похоже, что это может быть единственным обходным путем.

0 голосов
/ 10 декабря 2010

Это должно работать.

- (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);
    }
}
0 голосов
/ 27 августа 2010

Да, я считаю, что вы должны решить эту проблему, имея несколько XIB. Я помню, как видел это решение в одной из книг, которые читал в прошлом. Если нет, у вас есть игра с переводом и позицией объекта в представлении ... лучше иметь отдельный XIB.

0 голосов
/ 27 октября 2009

Вы можете использовать объект UIApplication для принудительной установки определенной ориентации устройства.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
0 голосов
/ 27 октября 2009

К сожалению, ваши подпредставления спрашивают только о том, какие ориентации они поддерживают, когда происходит изменение ориентации.

Итак, я заканчиваю настройку ориентации, прежде чем помещать новый контроллер вида в стек, если я знаю, что он изменился:

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 

Да, это неподдерживаемый вызов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...