C# 返回键不存在';无法在UIAlertView上的UIExtField中工作。。西格塞格夫

C# 返回键不存在';无法在UIAlertView上的UIExtField中工作。。西格塞格夫,c#,ios,xamarin.ios,uitextfield,uialertview,C#,Ios,Xamarin.ios,Uitextfield,Uialertview,当我在UIViewController中使用UITextField时,我能够用ShouldReturn捕捉返回键的键盘事件: public override void ViewDidLoad () { this.txtPassword.ShouldReturn = (tf) => { tf.ResignFirstResponder(); return true;

当我在
UIViewController
中使用
UITextField
时,我能够用
ShouldReturn
捕捉返回键的键盘事件:

public override void ViewDidLoad ()
{       
    this.txtPassword.ShouldReturn = (tf) => 
    {               
        tf.ResignFirstResponder();              
        return true;
    };
}
public override void ViewDidLoad ()
{

    base.ViewDidLoad ();            
    loginScreen = new UIAlertView();
    loginScreen.Title = "Login";            
    loginScreen.AlertViewStyle = UIAlertViewStyle.LoginAndPasswordInput;//type login and pass
    loginScreen.AddButton ("Cancel");
    //username
    UITextField usernameField = loginScreen.GetTextField(0);
    usernameField.KeyboardType = UIKeyboardType.Default;
    usernameField.ReturnKeyType = UIReturnKeyType.Next;
    usernameField.ClearButtonMode = UITextFieldViewMode.WhileEditing;
    //password
    UITextField passwordField = loginScreen.GetTextField(1);
    passwordField.KeyboardType = UIKeyboardType.Default;
    passwordField.ReturnKeyType = UIReturnKeyType.Next;
    passwordField.ClearButtonMode = UITextFieldViewMode.WhileEditing;

    //(Error SIGSEV happens here!!! and the resignfirstresponder doesn't work)
    passwordField.ShouldReturn = (tf) => 
    {               
        tf.ResignFirstResponder();
        return true;
    } ;
    loginScreen.Show();
。。。但是当我使用
UIAlertView
时,我在尝试使用
ShouldReturn
时遇到了一个SIGSEGV错误:

public override void ViewDidLoad ()
{       
    this.txtPassword.ShouldReturn = (tf) => 
    {               
        tf.ResignFirstResponder();              
        return true;
    };
}
public override void ViewDidLoad ()
{

    base.ViewDidLoad ();            
    loginScreen = new UIAlertView();
    loginScreen.Title = "Login";            
    loginScreen.AlertViewStyle = UIAlertViewStyle.LoginAndPasswordInput;//type login and pass
    loginScreen.AddButton ("Cancel");
    //username
    UITextField usernameField = loginScreen.GetTextField(0);
    usernameField.KeyboardType = UIKeyboardType.Default;
    usernameField.ReturnKeyType = UIReturnKeyType.Next;
    usernameField.ClearButtonMode = UITextFieldViewMode.WhileEditing;
    //password
    UITextField passwordField = loginScreen.GetTextField(1);
    passwordField.KeyboardType = UIKeyboardType.Default;
    passwordField.ReturnKeyType = UIReturnKeyType.Next;
    passwordField.ClearButtonMode = UITextFieldViewMode.WhileEditing;

    //(Error SIGSEV happens here!!! and the resignfirstresponder doesn't work)
    passwordField.ShouldReturn = (tf) => 
    {               
        tf.ResignFirstResponder();
        return true;
    } ;
    loginScreen.Show();

我不知道到底发生了什么,这可能是一个bug或者我做错了什么?

在ViewDidLoad范围内创建的对象在方法执行后应该保持活动状态(而不是垃圾收集),必须在包含的类中有一个引用

private UIAlertView _loginScreen; // Declare reference.
private UITextField _usernameField; // Declare reference.
private UITextField _passwordField; // Declare reference.

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();            
    _loginScreen = new UIAlertView(); // Set reference.
    _loginScreen.Title = "Login";            
    _loginScreen.AlertViewStyle = UIAlertViewStyle.LoginAndPasswordInput;
    _loginScreen.AddButton ("Cancel");
    //username
    _usernameField = _loginScreen.GetTextField(0); // Set reference.
    _usernameField.KeyboardType = UIKeyboardType.Default;
    _usernameField.ReturnKeyType = UIReturnKeyType.Next;
    _usernameField.ClearButtonMode = UITextFieldViewMode.WhileEditing;
    //password
    _passwordField = _loginScreen.GetTextField(1); // Set reference.
    _passwordField.KeyboardType = UIKeyboardType.Default;
    _passwordField.ReturnKeyType = UIReturnKeyType.Next;
    _passwordField.ClearButtonMode = UITextFieldViewMode.WhileEditing;

    //(Error SIGSEV happens here!!! and the resignfirstresponder doesn't work)
    _passwordField.ShouldReturn = (tf) => // Use reference.
    {
        // This delegate will be executed at a later time, ensure its owner
        // object is rooted with a reference.
        tf.ResignFirstResponder();
        return true;
    } ;
    _loginScreen.Show();
}
用户poupou当然是第一个回答这个问题的人,但我想把它和示例代码放在一起,因为这个bug咬了我太多次了。这很难调试,并且可能在垃圾收集后意外发生

我的经验法则;无论何时使用
new
或factory方法,都应存储引用,除非对象超出范围,或已嵌套到另一个具有引用的对象中

由于这个原因,我在字段前面加了一个下划线,它表示“这个对象将在这个对象的方法范围内存在,并且可以很容易地与方法变量(没有下划线的变量)区分开来。”


现在,对于这种情况,
GetTextField()
似乎创建了一个包装器对象,而不是一个引用。尽管
loginScreen
字段是根字段,但从
GetTextField()返回的对象
不是,而且容易垃圾收集。我认为这是由于意外行为导致的MonoTouch API中的一个错误。

在ViewDidLoad范围内创建的对象在方法执行后应该保持活动状态(而不是垃圾收集),必须在包含的类中具有引用

private UIAlertView _loginScreen; // Declare reference.
private UITextField _usernameField; // Declare reference.
private UITextField _passwordField; // Declare reference.

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();            
    _loginScreen = new UIAlertView(); // Set reference.
    _loginScreen.Title = "Login";            
    _loginScreen.AlertViewStyle = UIAlertViewStyle.LoginAndPasswordInput;
    _loginScreen.AddButton ("Cancel");
    //username
    _usernameField = _loginScreen.GetTextField(0); // Set reference.
    _usernameField.KeyboardType = UIKeyboardType.Default;
    _usernameField.ReturnKeyType = UIReturnKeyType.Next;
    _usernameField.ClearButtonMode = UITextFieldViewMode.WhileEditing;
    //password
    _passwordField = _loginScreen.GetTextField(1); // Set reference.
    _passwordField.KeyboardType = UIKeyboardType.Default;
    _passwordField.ReturnKeyType = UIReturnKeyType.Next;
    _passwordField.ClearButtonMode = UITextFieldViewMode.WhileEditing;

    //(Error SIGSEV happens here!!! and the resignfirstresponder doesn't work)
    _passwordField.ShouldReturn = (tf) => // Use reference.
    {
        // This delegate will be executed at a later time, ensure its owner
        // object is rooted with a reference.
        tf.ResignFirstResponder();
        return true;
    } ;
    _loginScreen.Show();
}
用户poupou当然是第一个回答这个问题的人,但我想把它和示例代码放在一起,因为这个bug咬了我太多次了。它很难调试,并且可能在垃圾收集后意外发生

我的经验法则是:无论何时使用
new
或factory方法,都应该存储引用,除非对象超出范围,或者已经嵌套到另一个具有引用的对象中

由于这个原因,我在字段前面加了一个下划线,它表示“这个对象将在这个对象的方法范围内存在,并且可以很容易地与方法变量(没有下划线的变量)区分开来。”


现在,对于这种情况,
GetTextField()
似乎创建了一个包装器对象,而不是一个引用。尽管
loginScreen
字段是根字段,但从
GetTextField()
返回的对象不是根字段,并且容易进行垃圾收集。我认为这是由于意外行为导致的MonoTouch API中的错误。

当GC收集(托管)实例(例如passwordField)时,可能会发生这种情况。现在,您提供的代码看起来是正确的,但是(稍后)可能会允许处置
loginScreen
(这也允许处置文本字段)。你能提供一个完整的测试用例吗?您可以将此附加到一个关于感谢的bug报告中!我在MT 5.2.11上使用了完全相同的代码,但有一个小区别:我的ShouldReturn看起来是这样的:pwd.ShouldReturn=delegate{passwordField.ResignFirstResponder();return true;}-因此我捕获了我想要辞职的文本字段,这似乎阻止了收集。当GC收集(托管)实例时,可能会发生这种情况(例如,passwordField)。现在您提供的代码看起来是正确的,但可能(稍后)有什么东西允许处置
loginScreen
(这也允许处置文本字段)。您能提供完整的测试用例吗?您可以在上附加这样的错误报告谢谢!我在MT 5.2.11上使用完全相同的代码,但有一个小小的区别:我的ShouldReturn如下所示:pwd.ShouldReturn=delegate{passwordField.ResignFirstResponder();return true;}-所以我捕获了我想退出的文本字段,这似乎阻止了收集。用户要求的UITextView不是UITextField@MyKuLLSKI发生SIGSEGV错误的原因是ShouldReturn lambda中引用的垃圾收集UITextField(请参阅tf参数)。这是问题所在。与UIAlertView无关。请在投票前阅读。用户要求的UITextView不是UITextField@MyKuLLSKI发生SIGSEGV错误的原因是ShouldReturn lambda中引用的垃圾收集UITextField(请参阅tf参数).这是问题所在。与UIAlertView无关。请在投票前阅读。