Подтвердить что ты не робот

В чем разница между UIApplication.sharedApplication.delegate.window и UIApplication.sharedApplication.keyWindow?

Может кто-нибудь помочь мне понять разницу между следующими двумя строками:

[UIApplication.sharedApplication.delegate.window addSubview:myView];
[UIApplication.sharedApplication.keyWindow addSubview:myView];
4b9b3361

Ответ 1

Они могут быть одинаковыми на iOS. Когда они отличаются, обычно вы представляете другое окно, кроме основного окна делегата приложения. В вашем приложении может быть много окон, но только keyWindow - это окно, которое видно на экране и получает события (например, UIAlert, когда он виден, а получение событий - это ключевое окно): https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/WindowAndScreenGuide/WindowScreenRolesinApp/WindowScreenRolesinApp.html

из документации:

  • Для UIApplication.sharedApplication.delegate.window:

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

то есть это свойство window, которое имеется в вашем файле AppDelegate.h.

  • Для UIApplication.sharedApplication.keyWindow:

Это свойство содержит объект UIWindow в массиве windows, который Совсем недавно было отправлено сообщение makeKeyAndVisible.

На iOS вы вызываете makeKeyAndVisible в вашем AppDelegate.m внутри

application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Вы сделали созданное окно appDelegate keyWindow. Обычно банковские приложения переключают ключевое окно, когда приложение помещается в фоновом режиме, чтобы защитить конфиденциальную информацию пользователей, когда дважды нажимается кнопка "Домой", и переключаться обратно в главное окно делегата, когда приложение находится на переднем плане.

Этот ответ находится в сотрудничестве с: @SipkeSchoorstra, @D-Mx и @andyDarwin

Ответ 2

Для большинства применений они будут одинаковыми... но не всегда.

[UIApplication sharedApplication].keyWindow - это окно, которое в настоящее время отображается на устройстве. Обычно это окно приложения, но может быть системным окном.

[UIApplication sharedApplication].delegate.window - это окно, в котором предполагается использовать ваше приложение.

Какой из них следует использовать? Хорошо, что все зависит от контекста.

Если вы обновляете часть своего приложения, вы должны добавить представления в окно своего приложения. Это почти всегда то, что вы хотите сделать.

Лично я всегда использую [[UIApplication sharedApplication].delegate.window addSubview:view] или [self.view.window addSubView:view] (внутри UIViewController), когда мне нужно добавить представление непосредственно в окно.

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

Ответ 3

Ответ Basheer_CAD неверен. Они не всегда одинаковы в iOS.

Ответ Джеффри Томас правильный, и позвольте мне привести конкретный пример.

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"keyWindow --------> %@",[UIApplication sharedApplication].keyWindow.rootViewController);
    NSLog(@"delegate.window --> %@",[UIApplication sharedApplication].delegate.window.rootViewController);
    NSLog(@"self.view.window -> %@",self.view.window.rootViewController);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
    [alert show];
    NSLog(@"keyWindow --------> %@",[UIApplication sharedApplication].keyWindow.rootViewController);
    NSLog(@"delegate.window --> %@",[UIApplication sharedApplication].delegate.window.rootViewController);
    NSLog(@"self.view.window -> %@",self.view.window.rootViewController);
}

Вывод:

keyWindow --------> (null)
delegate.window --> <ViewController: 0x10030c0e0>
self.view.window -> (null)
keyWindow --------> <UIApplicationRotationFollowingController: 0x100204510>
delegate.window --> <ViewController: 0x10030c0e0>
self.view.window -> <ViewController: 0x10030c0e0>

Когда viewDidLoad, на самом деле окно еще не готово, поэтому для системного окна ничего нет. UIAlertView может доминировать над окном, поэтому вы не можете получить нужное окно.

Ответ 4

Простейшей настройкой является просто один UIWindow. Обычно это окно хранится как свойство в вашем делете приложения. keyWindow - это тот, который предназначен для приема клавиатуры и других событий, не связанных с касанием. Ключевым окном может быть только одно окно за раз. Поэтому, если вы добавите второе окно и сделаете его keyWindow (через [window makeKeyAndVisible]), ваши строки возвратят разные окна!