【问题标题】:UITextField text jumpsUITextField 文本跳转
【发布时间】:2015-09-24 15:32:19
【问题描述】:

我有 ViewController 和 2 个 UITextField 元素:登录名和密码。我为这些字段设置了委托,其中包括以下代码:

func textFieldShouldReturn(textField: UITextField) -> Bool {
    if textField === self.loginField {
        self.loginField.resignFirstResponder()
        self.passwordField.becomeFirstResponder()
        return false
    }

    return true
}

当他按下键盘上的下一步按钮时,此逻辑应将用户从登录文本字段切换到密码。但我遇到了故障:之后

self.passwordField.becomeFirstResponder()

登录字段中的文本跳转到左上角并返回。更奇怪的是:此故障仅在第一次重现,然后您需要重新创建 ViewController 以观察此行为

这是故障视频http://tinypic.com/player.php?v=6nsemw%3E&s=8#.VgVb3cuqpHx

我最终得到了这个:

func textFieldShouldReturn(textField: UITextField) -> Bool {
    if textField === self.loginField {
        self.loginField.resignFirstResponder()
        // Shitty workaround. Hi, Apple!
        self.loginField.setNeedsLayout()
        self.loginField.layoutIfNeeded()

        self.passwordField.becomeFirstResponder()
        return false
    }

    return true
}

【问题讨论】:

标签: ios swift uitextfield


【解决方案1】:

基于此处发布的其他一些想法,这是一个易于实施、适用于所有情况(对我而言)并且似乎没有任何副作用的解决方案:

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    // Workaround for the jumping text bug.
    [textField resignFirstResponder];
    [textField layoutIfNeeded];
}

如果您要从 -textFieldShouldReturn: 以编程方式转到下一个字段,或者如果用户只是触摸另一个响应者,则此解决方案适用。

【讨论】:

  • 这真是太棒了,也是最简单的答案:)
  • 如果文本可见,这确实有效。但是,如果文本将 secureTextEntry 设置为 YES,则无法解决问题。
  • 终于!完美修复 +1
【解决方案2】:

UITextField 子类中,您可以执行以下操作:

-(BOOL)resignFirstResponder
{
    BOOL resigned = [super resignFirstResponder];
    [self layoutIfNeeded];
    return resigned;
}

这里的诀窍是确保您在调用layoutIfNeeded 之后 resignFirstResponder 已被调用。

这样做非常方便,因为您不需要自己在委托回调中调用 resignFirstResponder,因为这会导致我在 UIScrollView 中出现问题,但上述方法不会:)

【讨论】:

  • 谢谢,这是我的解决方案!
  • @iamnichols 救了我。
【解决方案3】:
func textFieldDidEndEditing(_ textField: UITextField) {

    textField.layoutIfNeeded()
}

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
【解决方案4】:

使用这段代码可以避免 UITextField 中文本的跳转。

- (BOOL) textFieldShouldReturn:(UITextField *)textField{

      if(textField == self.txtUserName){
        [self.txtEmail becomeFirstResponder];
      }
      else if (textField == self.txtEmail){
        [self.txtPassword becomeFirstResponder];
      }
      else if (textField == self.txtPassword){
        [self.txtConfirmPassword becomeFirstResponder];
      }
      else if (textField == self.txtConfirmPassword){
        [self.txtFirstName becomeFirstResponder];
      }
      else{
        [textField resignFirstResponder];
      }

   return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
   [textField resignFirstResponder];
   [textField layoutIfNeeded];
}

【讨论】:

    【解决方案5】:

    我也面临同样的问题。下面的代码对我有用。

    func textFieldDidEndEditing(_ textField: UITextField) {
    
        textField.layoutIfNeeded()
    }
    

    【讨论】:

      【解决方案6】:

      更多“通用”选项是在 UITextField 子类中使用通知:

       - (void)setupJumpingTextWorkaround {
          [[NSNotificationCenter defaultCenter] addObserver:self
                                                   selector:@selector(forceLayout)
                                                       name:UITextFieldTextDidEndEditingNotification object:self];
      }
      
      - (void)forceLayout {
              [self setNeedsLayout];
              [self layoutIfNeeded];
          }
      

      别忘了退订

      【讨论】:

        【解决方案7】:

        根据我对this的了解:

        当您在键盘回调中处理布局更改或动画将显示和隐藏通知时,可能会导致此问题(通常在您希望将文本字段向上推以使键盘不会隐藏它的情况下)。

        解决方案: 我在做 layoutIfNeeded 时遇到了这个问题,每次键盘都会显示被调用,假设它是安全的,显然它不是,所以当我只在需要更改帧时进行检查时,跳转停止了。

        【讨论】:

          【解决方案8】:

          我不给我的文本字段代表。相反,我创建了一个 IBAction 并将其附加到“退出时结束”事件。这种方法也会出现故障,但仅限于 iOS 9。它看起来是一个操作系统错误。

          我的动作是这样的:

          @IBAction func textFieldAction(sender: UITextField) {
              if sender === usernameField {
                  passwordField.becomeFirstResponder()
              }
          }
          

          有了上面,故障就会发生,但是当我做下面的时候,故障就消失了:

          @IBAction func textFieldAction(sender: UITextField) {
              if sender === usernameField {
                  sender.resignFirstResponder()
                  passwordField.becomeFirstResponder()
              }
          }
          

          我似乎不需要打电话给setNeedsLayout()

          【讨论】:

            猜你喜欢
            • 2016-01-04
            • 2017-08-23
            • 2015-08-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多