键盘仅在隐藏文本字段时移动视图

时间:2016-04-04 14:40:45

标签: ios swift user-interface uiscrollview keyboard

我正试图让我的应用程序在键盘出现时移动视图,到目前为止结果已经......混合至少说。我可以让它移动,事情是硬编码或仅部分工作。

我的视图中有多个Textfields,当我点击它们时,有时取决于我的滚动位置,它被键盘隐藏。

现在我需要我的应用程序做的是仅当活动文本字段被键盘隐藏时才移动视图以查看文本字段。

视图的我的层次结构如下:

Scene Hierarchy

所以我有一个Scroll视图,在滚动视图中我有一个名为ContentView的UIView,在ContentView中我有我的所有文本字段和标签。

事情是,我不能硬编码,因为我的应用程序是通用的,我需要键盘移动视图只有它隐藏文本字段。因为在用户在iPad上的情况下,View可能永远不必移动

我使用了以下Stack溢出答案而没有结果:

Swift: Scroll View only when a TextField or Button is hidden by the Keyboard

Move view with keyboard using Swift

这是我的代码,实际上来自其中一个答案:

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NewPaxController.keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NewPaxController.keyboardWillHide), name: UIKeyboardWillHideNotification, object: nil)

}



func keyboardWillShow(notification:NSNotification) {
    if keyboardIsPresent == false {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            self.ContentView.frame.origin.y -= keyboardSize.height
            keyboardIsPresent = true
        }
    }
}

func keyboardWillHide(notification:NSNotification) {
    if keyboardIsPresent == true {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            self.ContentView.frame.origin.y += keyboardSize.height
            keyboardIsPresent = false
        }
    }
}

我几乎100%确定我的所有错误都来自于我有一个ContentView ......但在我的情况下我需要它。在此先感谢您的帮助

3 个答案:

答案 0 :(得分:1)

以下是它的代码,非常简单,但如果你仍然需要帮助,我会进一步解释。

domain\username

编辑:一个简单的#pragma mark - Keyboard Observer events -(void)keyboardWillShow:(NSNotification*)notification { NSDictionary *info = [notification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; keyboardHeight = kbSize.height; [self updateScrollViewPosition]; } -(void)keyboardDidChange:(NSNotification *)notification { NSDictionary *info = [notification userInfo]; CGSize kbSizeBegin = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; CGSize kbSizeEnd = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; if (kbSizeBegin.height != kbSizeEnd.height) { keyboardHeight = kbSizeEnd.height; if (activeTextField && [activeTextField isFirstResponder]) { [self updateScrollViewPosition]; } } } -(void)keyboardWillHide:(NSNotification*)notification { keyboardHeight = 0; activeTextField = nil; [self resignAllTextFields]; } #pragma mark - UITextFieldDelegate Methods - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { activeTextField = textField; return YES; } - (void)textFieldDidBeginEditing:(UITextField *)textField { activeTextField = textField; [self updateScrollViewPosition]; } - (BOOL)textFieldShouldReturn:(UITextField *)textField { keyboardHeight = 0; activeTextField = nil; [textField resignFirstResponder]; return YES; } #pragma mark - Update Method -(void)updateScrollViewPosition { if (keyboardHeight > 0 && activeTextField) { CGRect frame = activeTextField.frame; CGFloat yPoint = scrollView.frame.origin.y+frame.origin.y+frame.size.height+8.0; CGFloat height = self.view.frame.size.height-keyboardHeight; CGFloat diff = yPoint-height; if (diff > 0.0) { [scrollView setContentOffset:CGPointMake(0, diff) animated:YES]; } else { CGFloat diff = scrollView.contentSize.height-scrollView.contentOffset.y; if (diff<scrollView.frame.size.height) { diff = scrollView.contentSize.height-scrollView.frame.size.height; if (diff < 0) { diff = 0.0; } [scrollView setContentOffset:CGPointMake(0, diff) animated:YES]; } } } else { CGFloat diff = scrollView.contentSize.height-scrollView.contentOffset.y; if (diff<scrollView.frame.size.height) { diff = scrollView.contentSize.height-scrollView.frame.size.height; if (diff < 0) { diff = 0.0; } [scrollView setContentOffset:CGPointMake(0, diff) animated:YES]; } } } #pragma mark 方法。 resignAllTextFields是包含所有containerView

的视图
UITextField

答案 1 :(得分:1)

键盘出现时,不能修改框架

相反,您需要将scrollview scrollView.contentInset.bottom的底部插入从零设置为键盘高度。键盘消失后,将插入设置回零。

只需10行代码即可解决整个问题。

从字面上获取通知的键盘高度,在显示KB时将其存储在类中的局部变量,并使用该值在委托回调/事件处理程序方法中设置insets。

这里的诀窍是设置非零插图将有效地滚动滚动视图以及为您提供的内容,这也将推动当前文本字段。

答案 2 :(得分:1)

您应首先尝试使用以下代码找到UITextField实例。

extension UIView {

    func firstResponder() -> UIView? {
        if self.isFirstResponder() {
            return self
        }

        for subview in self.subviews {
            if subview.isFirstResponder() {
                return subview
            }
        }

        return nil
    }

}

keyboardWillShow:函数中,确定键盘出现时文本字段是否可见。

func keyboardWillShow(notification:NSNotification) {
    if keyboardIsPresent == false {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue(),
            let inputView = self.ContentView.firstResponder()
            where inputView.frame.maxY > self.ContentView.frame.size.height - keyboardSize.height {

            self.ContentView.frame.origin.y -= keyboardSize.height
            keyboardIsPresent = true

        }
    }
}

如果将视图移走,只能将视图移回隐藏功能。