0

I'm creating an iOS 8 Custom Keyboard extension primarily using AutoLayout in my XIB. The last step of layout is adding the keyboard keys programmatically. To do this, I need a valid width to properly space keys.

Most StackOverflow posts and references I have read says to perform programmatic layout in viewDidLayoutSubviews. Most posts say that self.view / self.inputView will not have a valid size in viewDidLoad so viewDidLayoutSubviews is the right place to do it.

However, self.inputView.bounds and self.view.bounds (and .frame) give me 0 widths in viewDidLayoutSubviews in some cases.

Oddly, this only seems to happen in iPhone apps that Auto-Scale/Auto-Zoom for iPhone 6's form factor. Zynga's Words With Friends and my old version of Facebook seems to be one of these.

Can anyone help with this? Why would the inputView's bounds/frame ever be 0x0 in by the time viewDidLayoutSubviews gets called? Is there any other better method in which I should add components programmatically?

1 Answers1

0

I don't recommand the using of viewDidLayoutSubviews for keyboard extension. In viewDidLoad it won't have a valid size but you don't need a valid size to do this. Because you know the size of your keyboard as long as you get the device model (orientation is another thing).

As for your question, viewDidLayoutSubviews along with viewWillLayoutSubviews is sometimes called many times. And frame.bounds.width == 0 is also possible when the view is created. That's why I don't recommand using them. The reason I think is that the keyboard extension part of iOS 8 is still buggy and unstable.

If you really need to use viewDidLayoutSubviews, prevent it from getting wrongly called:

- (void) viewDidLayoutSubviews {
    if (self.view.frame.size.width == 0 || self.view.frame.size.height == 0)
        return; 
    // Do something
}
ljk321
  • 16,242
  • 7
  • 48
  • 60
  • Thanks! Unfortunately I have tried to use `[[UIScreen mainScreen] applicationFrame]`, `[[UIScreen mainScreen] bounds]` etc., but these are giving me the native resolution instead of the scaled app resolution. Again, this seems to just be a problem for apps (like Zynga games and a few others) that were written for 5/5s and automatically up-scaled/zoomed for iPhone 6. So, if I use the device's resolution to get the width, it ends up yielding a keyboard that is too wide for the scaled-up app. – user3934927 Jan 25 '15 at 23:25
  • @user3934927 Have you tried `[[UIScreen mainScreen] nativeBounds]`? It won't change whether the app is in scale mode or not. – ljk321 Jan 25 '15 at 23:29
  • @user3934927 My solution for scaled apps is to force the keyboard using resolution of 5/5s once scaled detected. – ljk321 Jan 25 '15 at 23:32
  • skyline75489--for some reason, `nativeBounds` and `bounds` are the same for me, even in scaled apps. Also, `[[UIScreen mainScreen] scale]` always comes back as `2`. I haven't figured out why this is--I figured it was a bug in the Keyboard Extension framework. – user3934927 Jan 26 '15 at 01:02
  • @user3934927 `[[UIScreen mainScreen] scale]` being 2 indicates that it's running on a retina device(4/4s/5/5s/6). It will be 3 on 6 Plus because the resolution of 6 Plus is kinda special. Anyway, it has nothing to do with whether the app is in scale mode. A significant difference with scaled mode is that `self.view.frame.width` will be 320 (like it on 5/5s) instead of 375(normal mode on 6) or 414(normal mode on 6 Plus). You can use this to detect whether an app is running in scaled mode. – ljk321 Jan 26 '15 at 02:20