43

在自定义键盘扩展中,我们不能使用

`didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation` 

sharedApplication

旋转时我需要检测键盘中的纵向或横向。

如何检测自定义键盘扩展中的方向何时发生变化?

4

10 回答 10

42

为了在方向更改时更新您的自定义键盘,请viewDidLayoutSubviewsUIInputViewController. 据我所知,当发生旋转时,总是会调用此方法。

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

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

希望这会有所帮助!

于 2014-06-28T13:23:43.333 回答
26

未弃用,适用于任何设备屏幕尺寸(包括Apple 将在今年发布的未来屏幕尺寸)。

在自定义键盘中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");
    }
}
于 2014-08-09T19:42:27.277 回答
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;
于 2014-09-28T23:35:53.063 回答
3

viewWillTransitionToSize:(CGSize)size withTransitionCoordinator: 在你的 viewController 中使用

于 2014-06-30T07:13:31.633 回答
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];
}
于 2014-11-12T12:01:59.633 回答
1

willRotateToInterfaceOrientation并且didRotateFromInterfaceOrientation可以使用,我只是在我的 iPad 上尝试了这个,在 iOS 8.1 上运行键盘。请注意,这些在 iOS 8 中已被弃用,但它们的替代品 ,willTransitionToTraitCollection尽管可能不会被调用,因为旋转时键盘的特征集合不会改变。

于 2014-11-15T05:23:39.920 回答
1

在 iOS 8.3 之前,你必须使用

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

这个不起作用(它应该是一个错误):

-(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

已弃用。

于 2015-04-27T08:00:07.487 回答
1

在某些情况下 [UIScreen 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");
}
于 2016-11-28T14:11:36.787 回答
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)
        }
    }
于 2019-11-08T09:43:50.193 回答
-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]; 
 }
于 2014-09-22T08:01:00.520 回答