如何在iOS 8中检测自定义键盘扩展中的方向更改?

时间:2014-06-11 15:29:12

标签: ios8 ios-app-extension custom-keyboard uiinputviewcontroller

在自定义键盘扩展程序中,我们无法使用

`didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation` 

sharedApplication

我需要在旋转时检测键盘上的人像或风景。

如何在自定义键盘扩展程序中检测方向更改?

10 个答案:

答案 0 :(得分:39)

要在方向更改时更新自定义键盘,请覆盖viewDidLayoutSubviews中的UIInputViewController。据我所知,当旋转发生时,总是调用此方法。

此外,由于传统[UIApplication sharedApplication] statusBarOrientation]无效,要确定当前方向,请使用以下代码段:

if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
    //Keyboard is in Portrait
}
else{
    //Keyboard is in Landscape
}

希望这有帮助!

答案 1 :(得分:25)

不推荐使用,适用于任何设备屏幕尺寸(包括未来的屏幕尺寸Apple will be releasing this year)。



在CustomKeyboard ViewController.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");
}

进行。










要么..................

有关此代码的更易于阅读的版本:

-(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");
    }
}

答案 2 :(得分:4)

有一种简单的方法,只需查看屏幕宽度:

 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;

答案 3 :(得分:2)

使用viewWillTransitionToSize:(CGSize)size withTransitionCoordinator: 在viewController里面

答案 4 :(得分:1)

- (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];
}

答案 5 :(得分:1)

可以使用

willRotateToInterfaceOrientationdidRotateFromInterfaceOrientation,我只是在运行iOS 8.1上的键盘的iPad上尝试过这个。请注意,这些在iOS 8中已弃用,但它们的替换willTransitionToTraitCollection未被调用,但可能是因为旋转时键盘的特征集合没有变化。

答案 6 :(得分:1)

在iOS 8.3之前,您必须使用

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                               duration:(NSTimeInterval)duration

这个不起作用(应该是一个bug):

-(void)viewWillTransitionToSize:(CGSize)size
      withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

在iOS 8.3及更高版本中,您最好使用

-(void)viewWillTransitionToSize:(CGSize)size
      withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

因为

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                               duration:(NSTimeInterval)duration

已弃用。

答案 7 :(得分:1)

在某些情况下[UI​​Screen mainscreen] .bounds可能无效。有时它会在viewWillTransitionToSize之后更新:

试试这个

- (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");
}

答案 8 :(得分:0)

对于那些正在 Swift 5中搜索答案的人。

通过覆盖func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation)方法。您可以检测设备方向。

这是我的自定义键盘的代码。

override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
        let screen = UIScreen.main.bounds
        if screen.width < screen.height {
            print("!!! portrait")
            let constraintForHeight:NSLayoutConstraint = NSLayoutConstraint(item: mainView!, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 0, constant: 325)
            constraintForHeight.isActive = true
            constraintForHeight.priority = UILayoutPriority.defaultHigh
            self.inputView?.addConstraint(constraintForHeight)
        } else {
            print("!!! landspace")
            let constraintForHeight:NSLayoutConstraint = NSLayoutConstraint(item: mainView!, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 0, constant: 210)
            constraintForHeight.isActive = true
            constraintForHeight.priority = UILayoutPriority.defaultHigh
            self.inputView?.addConstraint(constraintForHeight)
        }
    }

答案 9 :(得分:-2)

      - (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]; 
 }