当设备在 Beta 3 中旋转时如何正确处理自定义键盘

Eva*_*Chu 5 keyboard orientation ios ios8 ios-app-extension

所以我一直在研究这个自定义键盘一段时间,在 iOS 8 Beta 3 之前一切都很好。

我为 iPhone Portrait、iPhone Landscape、iPad Portrair、iPad Landscape 和 iPhone 4 Portrait 创建了 5 个 xib,问题就在这里。

在我的 KeyboardViewController:UIInputViewController 中,它是在我基于模板创建自定义键盘时创建的。

我有这个私有方法来确定我应该加载哪个 xib,基本上我只是检查屏幕宽度,然后删除所有子视图并添加新的键盘视图。

- (void)viewWillLayoutSubviews
{
    NSLog(@"[DEBUG] viewWillLayoutSubviews");
    [super viewWillLayoutSubviews];
    [self determineKeyboardNib:self.view.frame.size];
}
//
//- (void)viewDidLayoutSubviews
//{
//    NSLog(@"[DEBUG] viewDidLayoutSubviews");
//    [super viewDidLayoutSubviews];
//    [self determineKeyboardNib:self.view.frame.size];
//}

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    NSLog(@"[DEBUG] viewWillTransitionToSize:withTransitionCoordinator:");
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [self determineKeyboardNib:size];
}


/*
 * Determine which xib file to load based on the width of the screen
 */
- (void) determineKeyboardNib: (CGSize)size
{
    NSLog(@"[DEBUG] determineKeyboardNib: Enter if");
    KeyboardIBBackend *keyboard_view;
    // determine device
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        NSLog(@"[DEBUG] determineKeyboardNib: Enter iPad");
        // iPad
        if (size.width > 1000) {
            NSLog(@"[DEBUG] determineKeyboardNib: Enter iPad Landscape");
            // landscape
            keyboard_view = [KeyboardIBBackend keyboardiPadLandscapeView];
        }else{
            NSLog(@"[DEBUG] determineKeyboardNib: Enter iPad Portrait");
            // portrait
            keyboard_view = [KeyboardIBBackend keyboardiPadPortraitView];
        }
    }else{
        NSLog(@"[DEBUG] determineKeyboardNib: Enter iPhone");
        // iPhone
        if (size.width > 500){
            NSLog(@"[DEBUG] determineKeyboardNib: Enter iPhone Landscape");
            // landscape
            keyboard_view = [KeyboardIBBackend keyboardiPhone5LandscapeView];
        }else if(size.width > 450){
            NSLog(@"[DEBUG] determineKeyboardNib: Enter iPhone 4 Portrait");
            // portrait
            keyboard_view = [KeyboardIBBackend keyboardiPhone4LandscapeView];
        }else{
            NSLog(@"[DEBUG] determineKeyboardNib: Enter iPhone 5 Portrait");
            keyboard_view = [KeyboardIBBackend keyboardiPhonePortraitView];
        }
    }
    NSLog(@"[DEBUG] determineKeyboardNib: Exit if");
    keyboard_view.parentview = self;
    // remove previous keyboard view
    for (UIView *v in [self.view subviews]) {
        [v removeFromSuperview];
    }
    // add the newly determined view
    NSLog(@"[DEBUG] determineKeyboardNib: before addSubview");
    [self.view addSubview:keyboard_view];
    NSLog(@"[DEBUG] determineKeyboardNib: after addSubview");
}
Run Code Online (Sandbox Code Playgroud)

首先,我尝试将此方法放入 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator 但无论 Beta 2 还是 Beta 3 都没有被调用。

因此,我将该方法放在 viewWillLayoutSubviews: 中,并且在 Beta 3 之前它的作用就像一个魅力。

在 Beta 3 中,当我旋转设备时,会无限期调用 viewWillLayoutSubviews。我想那是因为在 detemineKeyboardNib 方法中,最后一行是

[self.view addSubview:keyboard_view]
Run Code Online (Sandbox Code Playgroud)

这可能导致它一次又一次地调用 viewWillLayoutSubviews。但是,Beta 2 中的情况并非如此。

然后我尝试在viewDidLayoutSubviews里面pur确定KeyboardNib,和上面一样。

所以我想知道在 Beta 3 中处理设备旋转的正确方法是什么。我相信 viewWillTransitionToSize:withTransitionCoordinator: 应该是正确的方法,但是当我旋转设备时它真的没有被调用......请在这里提供帮助。

谢谢,

小智 0

我不知道你是否已经修复了,但我发现似乎有效的解决方案是将代码放入 if 块中,该块仅在大小发生更改时运行,然后调用 super viewWillLayoutSubviews 。

像这样:

-(void)viewWillLayoutSubviews
{
  if(self.size.frame.width != self.someClassVariableToTrackWidth)
   {
       self.someClassVariableToTrackWidth = self.size.frame.width;
       //call stuff here
   }

[super viewWillLayoutSubviews];
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找更好的解决方案,因为这始终是一种黑客方法,当我找到它时,我会发布它。