可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In Custom Keyboard Extension , we can't use
`didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation`
and sharedApplication
.
I need to detect portrait or landscape in keyboard when rotate.
How can i detect when orientation change in Custom Keyboard extension?
回答1:
In order to update your custom keyboard when the orientation changes, override viewDidLayoutSubviews
in the UIInputViewController
. As far as I can tell, when a rotation occurs this method is always called.
Additionally, as the traditional [UIApplication sharedApplication] statusBarOrientation]
doesn't work, to determine the current orientation use the following snippet:
if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
//Keyboard is in Portrait
}
else{
//Keyboard is in Landscape
}
Hopefully this helps!
回答2:
Non-deprecated and will work on any device screen size (including future screen sizes Apple will be releasing this year).
In CustomKeyboardViewController.m
:
-(void)viewDidLayoutSubviews {
NSLog(@"%@", (self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height))) ? @"Portrait" : @"Landscape");
}
done.
Or..................
For a more easy to read version of this code:
-(void)viewDidLayoutSubviews {
int appExtensionWidth = (int)round(self.view.frame.size.width);
int possibleScreenWidthValue1 = (int)round([[UIScreen mainScreen] bounds].size.width);
int possibleScreenWidthValue2 = (int)round([[UIScreen mainScreen] bounds].size.height);
int screenWidthValue;
if (possibleScreenWidthValue1 < possibleScreenWidthValue2) {
screenWidthValue = possibleScreenWidthValue1;
} else {
screenWidthValue = possibleScreenWidthValue2;
}
if (appExtensionWidth == screenWidthValue) {
NSLog(@"portrait");
} else {
NSLog(@"landscape");
}
}
回答3:
There is a simple way, just looking at the screen width:
double width = [[UIScreen mainScreen] bounds].size.width;
double interfaceWidth = MIN([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
BOOL isPortrait = (width == interfaceWidth) ? YES : NO;
回答4:
use viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:
inside your viewController
回答5:
- (void)updateViewConstraints {
[super updateViewConstraints];
// Add custom view sizing constraints here
if (self.view.frame.size.width == 0 || self.view.frame.size.height == 0)
return;
[self.inputView removeConstraint:self.heightConstraint];
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
CGFloat screenH = screenSize.height;
CGFloat screenW = screenSize.width;
BOOL isLandscape = !(self.view.frame.size.width ==
(screenW*(screenW<screenH))+(screenH*(screenW>screenH)));
NSLog(isLandscape ? @"Screen: Landscape" : @"Screen: Potriaint");
self.isLandscape = isLandscape;
if (isLandscape) {
self.heightConstraint.constant = self.landscapeHeight;
[self.inputView addConstraint:self.heightConstraint];
} else {
self.heightConstraint.constant = self.portraitHeight;
[self.inputView addConstraint:self.heightConstraint];
}
//trigger default first view
[btn_gif sendActionsForControlEvents: UIControlEventTouchUpInside];
}
回答6:
willRotateToInterfaceOrientation
and didRotateFromInterfaceOrientation
can be used, I just tried this on my iPad running a keyboard on iOS 8.1. Note that those are deprecated in iOS 8, but their replacement, willTransitionToTraitCollection
, isn't called though likely because the trait collection doesn't change for the keyboard upon rotation.
回答7:
Before iOS 8.3, you have to use
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
This one does not work (it should be a bug):
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
On iOS 8.3 and later, you'd better use
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
because
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
is deprecated.
回答8:
In somecase [UIScreen mainscreen].bounds may not work. Sometimes it will update after viewWillTransitionToSize:
Try this
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
CGFloat realScreenHeight = MAX(screenSize.height, screenSize.width);
if(size.width == realScreenHeight)
NSLog(@"Landscape");
else
NSLog(@"Portrait");
}
回答9:
- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{ UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; // do whatever
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { }]; [super viewWillTransitionToSize: size withTransitionCoordinator: coordinator];
}