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无关。请在投票前阅读。