在文本字段中键入字符时移动的UI元素

时间:2018-01-23 03:08:34

标签: swift xcode textfield

当用户选择底部文本字段时,视图中的所有元素都会向上移动键盘的高度,直到用户解除键盘为止。

用户选择底部文本字段后会出现问题。最初元素都正确向上移动。但是,当用户键入第一个字符时,所有元素都会向下移动到原始位置。结果,用户再也看不到他们正在编辑的文本字段。一旦用户解开键盘,他们就会看到元素上升到原来的位置,然后再回到原来的位置。

我已经缩小了造成这个问题的原因,但我不明白为什么会这样。我的项目可以在https://github.com/JMNolan/memesicle

的GitHub上找到

我对Swift来说还是一个新手,对于一般的编码还是比较新的,所以非常感谢所有的帮助。对于不想使用GitHub的人,我还在下面列出了与此过程相关的代码片段

这是将元素移动到键盘高度

的原因
//moves the view up when the keyboard appears to keep the text field 
visible
    @objc func keyboardWillShow (notification: NSNotification){
        if bottomTextFieldActive == true{
            keyboardHeight = getKeyboardHeight(notification: 
notification)
            imagePickerView.frame.origin.y -= keyboardHeight
            topText.frame.origin.y -= keyboardHeight
            bottomText.frame.origin.y -= keyboardHeight
            toolbar.frame.origin.y -= keyboardHeight
        }
    }

当键盘被解除时,这是将元素向下移动键盘的高度

//moves the view down when the keyboard is dismissed to show the full view again
@objc func keyboardWillHide (notification: NSNotification){
    imagePickerView.frame.origin.y += keyboardHeight
    topText.frame.origin.y += keyboardHeight
    bottomText.frame.origin.y += keyboardHeight
    toolbar.frame.origin.y += keyboardHeight
    //shareButton.frame.origin.y += keyboardHeight
    print("keyboard just hid")
}

这就是调用上面的函数

func subscribeToKeyboardNotifications(){
        NotificationCenter.default.addObserver(self, selector: 
#selector(keyboardWillShow), name: 
NSNotification.Name.UIKeyboardWillShow, object: nil)

        NotificationCenter.default.addObserver(self, selector: 
 #selector(keyboardWillHide), name: 
NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

这是我在键盘高度上下移动元素时使用的键盘高度。

//get the height of the keyboard to determine how far up to move the view when editing the bottom text field
func getKeyboardHeight(notification: NSNotification) -> CGFloat {
    let userinfo = notification.userInfo
    let keyboardSize = userinfo![UIKeyboardFrameEndUserInfoKey] as!NSValue
    return keyboardSize.cgRectValue.height
}

1 个答案:

答案 0 :(得分:1)

当您输入UITextField时屏幕元素跳转的原因是由于您的视图限制。当您向视图添加约束时,您会失去以后通过更改其框架来移动子视图的能力 - 每次视图重新计算其子视图的位置时,它将返回使用约束提供的原始值并忽略你所做的框架更改。

由于您想要移动几个不同的屏幕元素,解决此问题的最简单方法是将所有子视图(文本字段,图像视图等)放在UIScrollView内,然后调整大小键盘出现时滚动视图的内容插入属性。这将完全取代更改帧大小的代码。 Apple has a help document about how to do this,但重要的部分如下:

  

调整内容通常涉及暂时调整一个或多个视图的大小并对其进行定位,以使文本对象保持可见。使用键盘管理文本对象的最简单方法是将它们嵌入UIScrollView对象或其子类之一,如UITableView。请注意,当内联编辑文本字段时,UITableViewController会自动调整其表格视图的大小并重新定位(要了解更多信息,请参阅视图控制器和基于导航的应用程序)。

     

当显示键盘时,您所要做的就是重置滚动视图的内容区域并将所需的文本对象滚动到位。因此,为了响应UIKeyboardDidShowNotification,您的处理程序方法将执行以下操作:

     
      
  1. 获取键盘的大小。

  2.   
  3. 按键盘高度调整滚动视图的底部内容插入。

  4.   
  5. 将目标文本字段滚动到视图中。

  6.   
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}