【问题标题】:Xamarin iOS - Navigate to next text field with return keyXamarin iOS - 使用返回键导航到下一个文本字段
【发布时间】:2019-11-11 21:01:23
【问题描述】:

我在 Xamarin 文档中找不到任何关于导航到表单上一系列文本字段中的下一个文本字段的内容,只有一个关于移除键盘的小教程。

为了简单起见,我使用了一个 txtUsername(tag 1) 文本字段和一个 txtPassword(tag 2) 文本字段。当我实现以下代码时,它不会转移到 Xamarin Studio。有谁知道这可以在 Xamarin Studio 中完成代码的方式,或者如果我可以将代码从 XCode 传输到 Xamarin Studio。

我正在使用以下代码:

- (BOOL)textFieldShouldReturn:(UITextField *)txtUsername{
    NSLog(@"textFieldShouldReturn:");
    if (txtUsername.tag == 1) {
        UITextField *txtPassword= (UITextField *)[self.view viewWithTag:2];
        [txtPassword becomeFirstResponder];
    }
    else {
        [txtUsername resignFirstResponder];
    }
    return YES;
}

提前致谢

【问题讨论】:

    标签: ios xamarin


    【解决方案1】:

    我认为最简单的方法是在 UITextFields 上使用 ShouldReturn 方法和 becomeFirstResponder 方法。例如,对于带有用户名和密码 UITextFields 的登录表单,如下所示(在您的 ViewDidLoad 方法中):

    Username = new UITextField();
    Username.ReturnKeyType = UIReturnKeyType.Next;
    Username.KeyboardType = UIKeyboardType.EmailAddress;
    Username.ShouldReturn = (tf) =>
        {
            Password.BecomeFirstResponder();
            return true;
        };
    View.Add(Username);
    
    Password = new UITextField();
    Password.SecureTextEntry = true;
    Password.ReturnKeyType = UIReturnKeyType.Go;
    Password.ShouldReturn = (tf) =>
        {
            // Do your login
            return true;
        };
    View.Add(Password);
    

    当您在“用户名”处于活动状态时单击“下一步”时,它会移动到“密码”字段。在密码字段中单击 Go 提交表单。

    【讨论】:

      【解决方案2】:

      我为每个表单(不仅仅是那些有 2 个字段的表单)编写了一个通用解决方案。

      我有一个带有这些方法的 BaseViewController:

      private UITextField[] formTextfields;
      protected void EnableNextKeyForTextFields(UITextField[] fields)
          {
              formTextfields = fields;
      
              foreach (var field in fields)
              {
                  field.ShouldReturn += ShouldReturn;
              }
          }
      
          private bool ShouldReturn(UITextField textField)
          {
              int index = Array.IndexOf(formTextfields, textField);
      
              if (index > -1 && index < formTextfields.Length - 1)
              {
                  formTextfields[index + 1].BecomeFirstResponder();
                  return true;
              }
              else if (index == formTextfields.Length - 1)
              {
                  formTextfields[index].ResignFirstResponder();
                  FormFinished();
              }
      
              return false;
          }
      
          protected virtual void FormFinished()
          {
              // this should be implemented on viewControllers using "EnableNextKeyForTextFields"
          }
      

      然后,在您的视图实现中,您只需将所有文本字段传递到一个数组中:

      EnableNextKeyForTextFields(new UITextField[] { NameField, SurnameField, EmailField, PasswordField });
      

      当用户在编辑数组的最后一个字段时单击“返回”时,将调用“FormFinished”方法,因此您可以在实现中覆盖它:

      protected override void FormFinished()
      {
          (ViewModel as RegisterViewModel).Register(); // or whatever you need to do here
      }
      

      我希望这对某人有用

      【讨论】:

        【解决方案3】:

        你可以利用这些功能

        http://iosapi.xamarin.com/?link=M%3aMonoTouch.UIKit.UIResponder.BecomeFirstResponder

        BecomeFirstResponder()
        

        http://iosapi.xamarin.com/?link=M%3aMonoTouch.UIKit.UIResponder.ResignFirstResponder

        ResignFirstResponder()
        

        根据文档,您应该像这样添加 textField Delegate 方法

        public virtual bool ShouldReturn (UITextField textField)
        {
        
           if (txtUsername.tag == 1) {
        
            UITextField txtPassword = (UITextField)this.view.ViewWithTag(2);
        
            txtPassword.BecomeFirstResponder();
           }
           else {
            txtUsername.ResignFirstResponder();
               }
        return true;
        }
        

        【讨论】:

        • 啊,是的,我没想到要查看 API 文档,而是查看了指南和教程。如果您能告诉我您的进展情况,那就太好了,我是 Xamarin 和 XCode 的新手,但我稍后回家后会尝试实施它们。
        • 非常感谢,我刚刚测试了这个方法,效果很好!
        • 随时@JonathanBick。
        • @satheeshwaran 嗨,我遇到了同样的问题,也许我遗漏了一些东西,ShouldReturn 代表应该在哪里?在 XCODE 中还是在我的 .xib 代码后面?我无法完成这项工作...... :(
        • @Amit:你把这个函数放在哪里了?在视图控制器构造函数下? txtPasswordtxtUsername 是 UIViewController 的属性吗?我不明白它的工作......
        【解决方案4】:

        以下是如何在 Xamarin.iOS 中实现的示例。可能还有其他更简单的方法可以做到这一点,但我找不到任何方法,这对我有用。

        我将 UITextFieldDelegate 子类化以添加自定义事件处理程序,然后在我的视图控制器代码中创建它的实例,将 lambda 表达式分配给自定义事件处理程序,以便我可以访问实例变量,并将此委托实例设置为 Delegate on我的 2 个扩展字段:

            public class LoginTextFieldDelegate : UITextFieldDelegate
            {
                public EventHandler<UITextField> OnShouldReturn;
        
                public override bool ShouldReturn(UITextField textField)
                {
                    if (OnShouldReturn != null)
                    {
                        OnShouldReturn(this, textField);
                    }
        
                    return true;
                }
            }
        

        然后在我的视图控制器ViewDidLoad方法中:

            var textDelegate = new LoginTextFieldDelegate
            {
                OnShouldReturn = (sender, textField) =>
                {
                    if (textField.Tag == txtEmailAddress.Tag)
                    {
                        txtPassword.BecomeFirstResponder();
                    }
                    else if (textField.Tag == txtPassword.Tag)
                    {
                        txtPassword.ResignFirstResponder();
                    }
                }
            };
        
            txtEmailAddress.Delegate = textDelegate;
            txtPassword.Delegate = textDelegate;
        

        不要忘记在代码/界面生成器中为每个 UITextField 设置不同的标签!

        【讨论】:

          【解决方案5】:

          使用here可用的类会更容易

          public override void ViewDidLoad ()
          {
              base.ViewDidLoad ();
          
              // Manage keyboard and tab order
              new [] {
                  usernameField, // Tab order = 0
                  passwordField, // Tab order = 1
                  emailField // Tab order = 2
              }.InitializeNavigationOnFields();
          }
          

          只需按照您希望它们通过键盘导航的顺序调用传递所有文本字段的方法。

          【讨论】:

            【解决方案6】:

            我最近在登录屏幕上实施了一个解决方案,它以非常简单和精确的方式处理问题。

            不确定这些属性和事件在第一次提出问题时是否存在,但现在它们会为其他需要它的人提供帮助。

                    Entry emailEntry = new Entry()
                    {
                        Keyboard = Keyboard.Email,
                        ReturnType = ReturnType.Next //Changes Return Button on Keyboard to 'Next'
                    };
            
                    emailEntry.Completed += (s, e) => passwordEntry.Focus();
            

            按下 Return 键时会触发 Completed 事件。然后我将 Focus 设置为我的 passwordEntry 字段。

                    Entry passwordEntry = new Entry()
                    {
                        IsPassword = true,
                        ReturnType = ReturnType.Go //Changes Return Button on Keyboard to 'Next'
                    }; 
            
                    passwordEntry.Completed += (s, e) => SignInClick(s, e); //SignInClick method handles the sign in functionality
            

            密码输入的 Completed 事件随后启动 SignInClick 方法,该方法以前仅由屏幕上的按钮处理。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-03-21
              • 2011-06-27
              • 2016-07-13
              • 1970-01-01
              • 1970-01-01
              • 2016-01-20
              • 1970-01-01
              相关资源
              最近更新 更多