Клавиша возврата не работает в UITextField для UIAlertView .. SIGSEGV - PullRequest
2 голосов
/ 01 декабря 2011

Когда я использую UITextField в UIViewController, я могу записать событие клавиатуры клавиши возврата с помощью ShouldReturn:

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

... но когда я использую UIAlertView Я получил ошибку SIGSEGV при попытке использовать ShouldReturn:

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();

Я не знаю, что именно происходит, возможно, это ошибка или я что-то не так делаю?

1 Ответ

0 голосов
/ 14 февраля 2013

Объекты, созданные в области действия 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 *Конечно, 1005 * был первым, кто ответил на этот вопрос, но я бы хотел добавить его с примером кода, так как эта ошибка меня слишком много кусала.Его сложно отладить, и он может неожиданно произойти после сборки мусора.

Мое эмпирическое правило;всякий раз, когда new или фабричный метод используется, ссылка должна сохраняться, если объект не выходит из области видимости или уже не вложен в другой объект со ссылкой.

По этой причине я ставлю поля с подчеркиванием, он сигнализирует «этот объект будет жить в пределах областей метода в этом объекте, и его можно легко отличить от переменных метода (без подчеркивания).

Теперь кажется, что для этого случая GetTextField() создаетобъект-обертка, а не ссылка. Хотя поле loginScreen является корневым, объект, возвращаемый из GetTextField(), не является объектом и подвержен сборке мусора. Я бы сказал, что это ошибка в API MonoTouch из-за непредвиденного поведения.

...