iOS:在iPad模式视图中获得键盘点的顶部?

时间:2015-05-20 22:35:50

标签: ios ipad frame modalviewcontroller uikeyboard

我需要调整一条消息栏'当键盘显示并且在使用iPad模态视图控制器时遇到问题。消息栏'应该在键盘显示时坐在键盘顶部,然后在键盘隐藏时位于模态的底部(一个消息应用程序样式)。

问题是我需要根据Modal的坐标系获得键盘框架的最高点。 我发现这个答案在理论上似乎是正确的,但不起作用(How can I find portion of my view which isn't covered by the keyboard (UIModalPresenationStyleFormSheet)?):

FYI当显示键盘时,主窗口中的键盘框架(即' keyboardFrame')=( - 84.0,526.0,768.0,264.0)。翻译为模态视图控制器坐标系时的键盘框架(即' newSize')=(-168.0,292.0,768.0,264.0)*

// Convert the keyboard rect into the view controller's coordinate system
// The fromView: nil means keyboardRect is in the main window's coordinate system
let newSize = self.view.convertRect(keyboardFrame, fromView: nil)

// And then this is the part that gets covered!
let keyboardCoveredHeight = self.view.bounds.height - newSize.origin.y
self.messageToolbar.bottomConstraint.constant = -keyboardCoveredHeight

enter image description here

3 个答案:

答案 0 :(得分:0)

我认为你遇到了两个问题之一(可能两个):

  1. 在iOS 8中,您必须从屏幕的坐标空间转换键盘的矩形
  2. 在iPad上,当显示键盘时,工作表视图有时会向上移动一点,在显示键盘后发生,因此您需要再次计算的结果viewWillLayoutSubviews
  3. 此处a sample project that does what you want

    对于后人来说,这是有趣的源代码:

    class TypingViewController: UIViewController {
    
        var keyboardHoverView: UIView! // your keyboard toolbar or whatever
        var lastKeyboardFrame : CGRect! // whenever you get a frame update, store it here
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            createKeyboardHoverView()
            observeKeyboard()
        }
    
        func createKeyboardHoverView() {
            // make your keyboard toolbar
            keyboardHoverView = view
        }
    
        func observeKeyboard() {
            NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
            NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
        }
    
        func keyboardWillShow(notification : NSNotification) {
            let dict = notification.userInfo!
            let frameValue = dict[UIKeyboardFrameEndUserInfoKey] as! NSValue
            lastKeyboardFrame = frameValue.CGRectValue()
    
            moveKeyboardView()
        }
    
        func keyboardWillHide(notification : NSNotification) {
            moveKeyboardView()
        }
    
        override func viewWillLayoutSubviews() {
            // this moves the view again, in case the modal view has shifted up
            moveKeyboardView()
        }
    
        func moveKeyboardView() {
            if lastKeyboardFrame != nil {
                // this conversion is used in iOS 8 and differs from most online tutorials
                let frameInThisView = self.view.convertRect(lastKeyboardFrame, fromCoordinateSpace: view.window!.screen.coordinateSpace)
    
                var newRect = keyboardHoverView.frame
                newRect.origin.y = frameInThisView.origin.y - CGRectGetHeight(newRect)
                keyboardHoverView.frame = newRect
    
                println("Setting rect: \(newRect)")
            }
        }
    }
    

答案 1 :(得分:0)

我最终使用熟悉的类别在iPad模式视图中获得正确的键盘框架:

- (CGFloat)heightCoveredByKeyboardOfSize:(CGSize)keyboardSize
{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGRect frameInWindow = [self convertRect:self.bounds toView:nil];
CGRect windowBounds = self.window.bounds;

CGFloat keyboardTop;
CGFloat heightCoveredByKeyboard;

//Determine height of the view covered by the keyboard relative to current rotation

switch (orientation)
{
    case UIInterfaceOrientationLandscapeLeft:
    case UIInterfaceOrientationLandscapeRight:
        keyboardTop = windowBounds.size.height - keyboardSize.height;
        heightCoveredByKeyboard = windowBounds.size.height - frameInWindow.origin.y - keyboardTop;
        break;
    case UIInterfaceOrientationPortraitUpsideDown:
    default:
        keyboardTop = windowBounds.size.height - keyboardSize.height;
        heightCoveredByKeyboard = CGRectGetMaxY(frameInWindow) - keyboardTop;
        break;
}

return MAX(0.0f,heightCoveredByKeyboard);
}

以及DAKeyboardControl(用于平移):

    // Use [unowned self] in closure for weak reference
    self.view.addKeyboardPanningWithFrameBasedActionHandler(nil, constraintBasedActionHandler: { [unowned self] (keyboardFrameInView, opening, closing) -> Void in
        if opening
        {
            if UIDevice.isIpad()
            {
                // iPad requires a different method due to use of modal view
                self.messageToolbar.bottomConstraint.constant = -self.view.heightCoveredByKeyboardOfSize(keyboardFrameInView.size)
            }
            else
            {
                self.messageToolbar.bottomConstraint.constant = -keyboardFrameInView.size.height
            }
        }

        if closing
        {
            self.messageToolbar.bottomConstraint.constant = 0
        }

        self.view.updateConstraintsIfNeeded()
        self.view.layoutIfNeeded()
    })

答案 2 :(得分:0)

可以在keyboardDidShowNotification 上以这种方式计算精确重叠

let parentRelativeFrame = view.convert(view.frame, to: nil)
let viewBottomVerticalOffset = parentRelativeFrame.origin.y + parentRelativeFrame.height
let overlap = viewBottomVerticalOffset - keyboardFrame.origin.y