How can I find portion of my view which isn't covered by the keyboard (UIModalPresenationStyleFormSheet)?

ぃ、小莉子 提交于 2019-12-04 09:54:15

Will's answer was the right idea but I had to tweak it quite a bit to get it right

extension UIView {
    func heightCoveredByKeyboardOfSize(keyboardSize: CGSize) -> CGFloat {
        let frameInWindow = convertRect(bounds, toView: nil)
        guard let windowBounds = window?.bounds else { return 0 }

        let keyboardTop = windowBounds.size.height - keyboardSize.height
        let viewBottom = frameInWindow.origin.y + frameInWindow.size.height

        return max(0, viewBottom - keyboardTop)
    }
}

Here's how I'm handling the keyboard with iPad form sheets:

- (void)UIKeyboardDidShowNotification:(NSNotification*)aNotification
{
    NSDictionary *userInfo = [aNotification userInfo];
    CGSize keyboardSize = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, [self.view heightCoveredByKeyboardOfSize:keyboardSize], 0.0);

    [UIView animateWithDuration:.25f animations:^{
        self.scrollView.contentInset = contentInsets;
        self.scrollView.scrollIndicatorInsets = contentInsets;
    }];
}

Category on UIView:

- (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:
            keyboardTop = windowBounds.size.width - keyboardSize.width;
            heightCoveredByKeyboard = CGRectGetMaxX(frameInWindow) - keyboardTop;
            break;
        case UIInterfaceOrientationLandscapeRight:
            keyboardTop = windowBounds.size.width - keyboardSize.width;
            heightCoveredByKeyboard = windowBounds.size.width - frameInWindow.origin.x - keyboardTop;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            keyboardTop = windowBounds.size.height - keyboardSize.height;
            heightCoveredByKeyboard = windowBounds.size.height - frameInWindow.origin.y - keyboardTop;
            break;
        default:
            keyboardTop = windowBounds.size.height - keyboardSize.height;
            heightCoveredByKeyboard = CGRectGetMaxY(frameInWindow) - keyboardTop;
            break;
    }

    return MAX(0.0f,heightCoveredByKeyboard);
}

I think I've found a pretty decent answer. You can use the convertRect:fromView: method on UIView to convert coordinate systems.

In swift code, the selector that UIKeyboardNotification calls look something like this:

func keyboardWasShown(notification: NSNotification) {
    let info = notification.userInfo!
    let keyboardRect = (info[UIKeyboardFrameEndUserInfoKey]! as NSValue).CGRectValue()

    // 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(keyboardRect, fromView: nil)

    // And then this is the part that gets covered!
    let keyboardCoveredHeight = self.view.bounds.height - newSize.origin.y
    // Note: you may have to use self.navigationController!.view.bounds.height if
    // you've wrapped your view in a navigation controller because this will 
    // include the height of the navigation bar

    // You can then adjust the content inset of the text view accordingly
    textView.scrollIndicatorInsets.bottom = keyboardCoveredHeight
    textView.contentInset.bottom = keyboardCoveredHeight
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!