почему этот другой код "addSubView" вызывает различия в поведении - PullRequest
8 голосов
/ 22 апреля 2011

Почему изменение приведенного ниже кода со старой на новую запись решает следующую проблему.

Код:

  // OLD Entry - Did not work
  //[self.window addSubview:navigationController.view];

  // NEW Entry - Fixed it
  self.window.rootViewController = self.navigationController;

Проблема при использовании старого кода:

  • Я использую UINavigationController и имею UITableViewController типа mainView изатем представление 2-го уровня, которое я помещаю в стек, давайте назовем его «подробный вид» UITableViewController.

  • Обычная навигация назад и вперед от основного к деталям работает нормально

  • НО при автоматическом запуске при запуске во 2-й вид (так как я сохраняю состояние) я получаю 2-й вид ОК, однако КНОПКИ ИНСТРУМЕНТОВ НЕ появляются в нижней части 2-го вида в этом случае.Когда я возвращаюсь на главную страницу (через стандартные схемы UINavigationController), а затем выбираю строку в UITableView и снова возвращаюсь в то же представление, элементы панели инструментов отображаются нормально.

  • Не удалось отследить это, но в итоге методом проб и ошибок я заметил, что это изменение в коде (см. Выше) в appDelegate (всех мест), похоже, решает проблему.

Любые идеи?

РЕДАКТИРОВАТЬ: для полноты вот полный метод

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
    NSManagedObjectContext *context = [self managedObjectContext];
    if (!context) {
        abort();  // TODO: Do better job here than abort
    }
    rootViewController.managedObjectContext = context;
     self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

РЕДАКТИРОВАТЬ 2: О, у меня есть файл NIB и у меня есть контроллер корневого представления / настройки окна в построителе интерфейса - так что яМне интересно, не смешиваю ли я здесь NIB и программный подход, что может вызвать проблемы?

EDIT 3: Также отмечено, что следующий код didFinishLaunchingWithOptions работал, когда я добавил "self.window.rootViewController = self.navigationController ".То есть без этой строки (что делает пример coredatabooks) я получаю проблему.

RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
    rootViewController.managedObjectContext = self.managedObjectContext;
    self.window.rootViewController = self.navigationController;  // WORKS WHEN I ADD THIS LINE IN FOR SOME REASON???

    // Configure and show the window
    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];

return YES;

1 Ответ

6 голосов
/ 22 апреля 2011

Разница между этими двумя методами заключается в том, что один запускает методы жизненного цикла представления, а другой - нет.

Т.е. установка window.rootViewController приведет к тому, что старый контроллер представления получит сообщения: viewDidDissaper viewWillDissapear и т. Д., В то время какновый контроллер представления получит viewWillApear, viewDidAppear и т. д.

addSubview: не делает этого.

Помогает ли это?

РЕДАКТИРОВАТЬ:

При подробном чтении вашего поста создается впечатление, что вы добавляете кнопки программно в методе viewDidAppear подробного просмотра.

Свойство rootViewController UIWindow было добавлено как4.0.В документации явно не упоминается, что это вызовет методы жизненного цикла представления, я узнал об этом через ошибки и следы, как и вы.(возможно, кто-то может поднять проблему в отношении документации Apple).

Если вам нужна обратная совместимость с 3.x, вы можете использовать этот пользовательский подкласс UIWindow.Мой код ниже.используйте window.djRootViewController = yourViewController вместо window.rootViewController.Он предназначен для использования в Интерфейсном конструкторе.

#import <UIKit/UIKit.h>

@interface DJWindow : UIWindow {

    UINavigationController* m_navigationController;
}

@property (nonatomic, retain) UIViewController* djRootViewController;

@end




#import "DJWindow.h"

@interface DJWindow()

- (void) customInit;

@end


@implementation DJWindow


- (id) initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        [self customInit];
    }
    return self;
}


- (void) customInit {
    m_navigationController = [[UINavigationController alloc] init];

    m_navigationController.navigationBarHidden = YES;

    [self addSubview:m_navigationController.view];
}

- (void) setRootViewController:(UIViewController *)rootViewController {
    NSLog(@"ERROR, do not set the rootViewController property, use djRootViewController instead");
}

- (void) setDjRootViewController:(UIViewController *)djRootViewController {

    if (djRootViewController == nil) {
        [m_navigationController setViewControllers:nil];
    } else {
        NSArray* vcArray = [NSArray arrayWithObject:djRootViewController];
        [m_navigationController setViewControllers:vcArray];
    }
}

- (UIViewController*) djRootViewController {

    return m_navigationController.visibleViewController;
}

- (void)dealloc
{
    [m_navigationController release];
    [super dealloc];
}


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