Смещение по UIWindow addSubview

У меня есть приложение на основе UITabBar, которое работает отлично. Однако при определенных обстоятельствах я показываю другой UIViewController. Теперь, что меня беспокоит, я должен правильно настроить рамку для тестового ниба (и только Test nib!). (В противном случае представление находится ниже строки состояния).

- (void)applicationDidFinishLaunching:(UIApplication *)application { if (condition) { UIViewController *vc = [[UIViewController alloc] initWithNibName:@"Test" bundle:nil]; // FIXME this should NOT be required CGRect r = vc.view.frame; r.origin.y += 20; vc.view.frame = r; [window addSubview:vc.view]; [window makeKeyAndVisible]; return; } [window addSubview:tabViewController.view]; [window makeKeyAndVisible]; } 

Так что, возможно, что-то не так с пробным наконечником? Не может быть. Испытательный наконечник работает по желанию в новом новом проекте. И новый чистый нить показывает те же симптомы. Так что что-то должно быть неправильно с кончиком MainWindow, правильно? Но UITabBarController отображается просто отлично.

Я немного запутался и исчерпал идеи здесь. Любые предложения, как отслеживать это?

Добавление корневого представления в UIWindow может быть затруднено, так как окно всегда перекрывает строку состояния. Поэтому рамка вашего корневого представления должна быть сброшена на [[UIScreen mainScreen] applicationFrame] чтобы она не перекрывала строку состояния. Мы обычно не должны беспокоиться об этом, потому что UIViewController меняет frameworks для нас … за исключением случаев, когда этого не происходит. Вот сделка:

  • Если вы создаете свой controller представления и его представление в одном и том же NIB, и вы вставляете представление под controllerом представления, он автоматически настраивает кадр представления.
  • Если вы создаете свой controller просмотра и его представление в одном и том же NIB, но вы подключаете представление к controllerу представления через выходное окно controllerа, а не вставляете его, controller не будет автоматически настраивать рамку представления.
  • Если вы создаете свой controller представления в одном NIB и подключаете его к представлению, определенному в отдельном NIB, установив свойство «NIB Name» controllerа представления в IB, он автоматически настроит кадр представления, но только если у вас также есть ” Изменить размер из NIB “.
  • Если вы создаете свой controller просмотра, вызывая -initWithNibName: bundle: он не будет автоматически настраивать кадр представления.
  • UITabBarController ожидает, что его представление будет добавлено в виде корневого представления windows, и поэтому всегда настраивает его собственный кадр представления, чтобы он соответствовал рамке приложения автоматически. (В результате вы заметите странный 20-пиксельный зазор, если вы когда-нибудь добавите представление UITabBarController в качестве подчиненного объекта, кроме windows.)

Я предполагаю, что Apple предположил, что -initWithNibName: bundle: обычно не используется для создания корневого представления windows, поэтому он не корректирует рамку в вашем случае. Измените его вручную, как вы это сделали, хорошо, и на самом деле рекомендуется в Руководстве по программированию View Controller для iPhone OS , но вы действительно должны использовать [[UIScreen mainScreen] applicationFrame] поскольку строка состояния не всегда высока в 20 пикселей (например, он выше, когда вы звоните по телефону.)

Это намного проще и работает (iOS 4.0 и более поздние версии)

 MyRootViewController *vc = [[MyRootViewController alloc] init]; [window setRootViewController:vc]; [vc release]; 

-setRootViewController автоматически добавляет представление controllerа в окно, поэтому вам не нужно беспокоиться об этом. Свойство (неатомное, удержание), таким образом, освобождая его после присвоения его окну, эффективно передает владение объектом в UIWindow и будет освобождено (и, следовательно, освобождено), когда окно будет освобождено. Вы могли бы, конечно, создать переменную экземпляра и сохранить ссылку на нее и опубликовать в -dealloc, если хотите сделать что-то с ним в других методах делегирования приложения. Я предпочитаю вышеуказанный метод, так как он автоматически заботится о очистке.

В случае, если вы этого не знаете, вы также можете освободить controllerы представлений сразу же после добавления своих представлений в любое другое представление в виде подчиненного представления или представления вида просмотра модальных представлений. Всякий раз, когда вид удаляется или удаляется из стека представлений, их соответствующие controllerы также будут освобождены.

Вам не нужно использовать initWithNibName, просто … alloc] init]; Сделаю.

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

 [vc setWantsFullScreenLayout:YES]; 

Чтобы повторить сказанное выше: Вот код, который мне пришлось использовать:

 #define MAIN_SCREEN_OFFSET_PIXELS 20 - (void) pushDownViewOnMainScreen { CGRect r = [[UIScreen mainScreen] applicationFrame]; r.origin.y -= MAIN_SCREEN_OFFSET_PIXELS; self.view.frame = r; } - (void) viewDidLoad { [self pushDownViewOnMainScreen]; // ... } 
  • Как добавить пользовательский вид в квоту annotations карты
  • Медленный запуск для AVAudioPlayer при первом воспроизведении звука
  • Использовать веб-службу WCF с помощью Objective-C на iPhone
  • Время ожидания NSURLConnection?
  • NSdate Предполагая неправильный часовой пояс
  • Предотвратите скрытие панели навигации UISearchDisplayController
  • 2 различных типа пользовательских UITableViewCells в UITableView
  • Перерыв на EXC_BAD_ACCESS в XCode?
  • Как изменить цвет выбранной строки в UIPickerView
  • UIScrollView горизонтальный пейджинг, как вкладки Mobile Safari
  • AVAudioPlayer: как изменить скорость воспроизведения аудио?
  • Давайте будем гением компьютера.