Reputation: 441
I have two slightly different layouts for my keyboard based on the orientation of the device. When I load up the keyboard at first, it looks fine. Here's the portrait version:
The initial constraint setup occurs within -viewDidLoad (of the UIInputViewController subclass)
portraitConstraints = [self constraintsForOrientation:UIInterfaceOrientationPortrait];
landscapeConstraints = [self constraintsForOrientation:UIInterfaceOrientationLandscapeRight];
[self.view addConstraints:portraitConstraints];
[self.view addConstraints:landscapeConstraints];
if ([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) {
[NSLayoutConstraint deactivateConstraints:landscapeConstraints];
} else {
[NSLayoutConstraint deactivateConstraints:portraitConstraints];
}
This part works, as it loads correctly regardless of initial orientation. However, once I rotate the device, everything goes wrong.
And then back to portrait:
For reference, the proper landscape version looks like this:
I update the constraints in -updateViewConstraints as follows:
- (void)updateViewConstraints {
if ([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) {
[NSLayoutConstraint deactivateConstraints:landscapeConstraints];
[NSLayoutConstraint activateConstraints:portraitConstraints];
} else {
[NSLayoutConstraint deactivateConstraints:portraitConstraints];
[NSLayoutConstraint activateConstraints:landscapeConstraints];
}
[super updateViewConstraints];
}
It seems like after the view changes it suddenly takes up more than full screen instead of just the keyboard area. Any ideas how I can fix this? Thanks.
Upvotes: 3
Views: 1963
Reputation: 11598
The issue appeared to be related to somehow implicitly overriding the height of the view that contained the keyboard. Although I didn't see anything that would force a resizing of the container view, explicitly setting the height of the container view got back to good, reproducible results.
I got the idea of manually constraining the keyboard's height from Apple's App Extension Programming Guide: Custom Keyboard.
Specifically, the relevant information was this:
You can adjust the height of your custom keyboard’s primary view using Auto Layout. By default, a custom keyboard is sized to match the system keyboard, according to screen size and device orientation. A custom keyboard’s width is always set by the system to equal the current screen width. To adjust a custom keyboard’s height, change its primary view's height constraint.
The following code lines show how you might define and add such a constraint:
CGFloat _expandedHeight = 500;
NSLayoutConstraint *_heightConstraint =
[NSLayoutConstraint constraintWithItem: self.view
attribute: NSLayoutAttributeHeight
relatedBy: NSLayoutRelationEqual
toItem: nil
attribute: NSLayoutAttributeNotAnAttribute
multiplier: 0.0
constant: _expandedHeight];
[self.view addConstraint: _heightConstraint];
NOTE
In iOS 8.0, you can adjust a custom keyboard’s height any time after its primary view initially draws on screen.
Here is the important method in a template answer based on this information:
- (void)updateViewConstraints {
if (self.keyboardHeightConstraint == nil) {
// Just starting with SOME value for the height
self.keyboardHeightConstraint =
[NSLayoutConstraint constraintWithItem:self.view
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:0.0f
constant:500.0f];
[self.view addConstraint:self.keyboardHeightConstraint];
}
// Obviously, these values will be changed based on device AND orientation
// These are bogus values...
if ([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) {
self.keyboardHeightConstraint.constant = 300.0f;
[NSLayoutConstraint deactivateConstraints:self.landscapeConstraints];
[NSLayoutConstraint activateConstraints:self.portraitConstraints];
} else {
self.keyboardHeightConstraint.constant = 400.0f;
[NSLayoutConstraint deactivateConstraints:self.portraitConstraints];
[NSLayoutConstraint activateConstraints:self.landscapeConstraints];
}
[super updateViewConstraints];
}
Upvotes: 3