Сбой приложения при изменении значения UIDatePicker для UITextField в UIAlertController

Я создаю экземпляр UIAlertController и назначаю UIDatePicker одному из его UITextField (ов) в качестве входного представления. Я также назначил сборщику обработчик события ValueChanged. UIDatePicker правильно показывает, когда упомянутый UITextField получает фокус, но когда я меняю значение даты, приложение вылетает.

Пожалуйста, рассмотрите приведенный ниже код.

var d = UIAlertController.Create( "Confirm", "Fill below with the required info.", UIAlertControllerStyle.Alert);

d.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, ((UIAlertAction obj) => SubmitAction(obj, d))));
d.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, null));

d.AddTextField((delegate(UITextField obj) {
    UIDatePicker picker = new UIDatePicker ();
    picker.ValueChanged += (object sender, EventArgs e) => { obj.Text = picker.Date.Description; };
    obj.InputView = picker;
}));

PresentViewController(d, true, null);

Опять же, сборщик показывает нормально. Приложение аварийно завершает работу при событии ValueChanged даже с ПУСТЫМ обработчиком picker.ValueChanged += (object sender, EventArgs e) => {};.

Никаких сбоев без добавления обработчика событий!

Этот код находится в обработчике события TouchUpInside кнопки.

Где я делаю неправильно?


person Shockwaver    schedule 24.12.2014    source источник


Ответы (1)


Я думаю, что вы перепутали методы событий в своем примере кода. TouchUpInside не будет срабатывать для средства выбора. Если вы хотите обновить содержимое текстового представления, если выбрано новое значение даты, вам нужно будет использовать:

picker.ValueChanged += (pickerSender, pickerArgs) =>
{
        obj.Text = picker.Date.Description;
};

Чтобы предотвратить сбой, вам нужно сохранить ссылку на экземпляр UIDatePicker, иначе он будет собран слишком рано. Самый простой способ - переместить средство выбора даты в область класса:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    // Perform any additional setup after loading the view, typically from a nib.
    this.btnTest.TouchUpInside += HandleTouchUpInside;
}

UIDatePicker picker;

void HandleTouchUpInside (object sender, EventArgs e)
{
    var d = UIAlertController.Create( "Confirm", "Fill below with the required info.", UIAlertControllerStyle.Alert);

    d.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, ((UIAlertAction obj) => {})));
    d.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, null));

    d.AddTextField((delegate(UITextField obj) {
        picker = new UIDatePicker ();
        picker.ValueChanged += (pickerSender, pickerArgs) =>
        {
            obj.Text = picker.Date.Description;
        };
        obj.InputView = picker;
    }));
    PresentViewController(d, true, null);
}
person Krumelur    schedule 24.12.2014
comment
Извините, я полностью перепутал сообщение: TouchUpInside был абсолютно нежелательным в ИСХОДНОМ ПОСТЕ. Требуемый обработчик события указан в заголовке ValueChanged. Я обновил его. Однако теперь я попытаюсь сохранить ссылку на область класса, как вы предложили. - person Shockwaver; 29.12.2014
comment
И это было абсолютно так! Слишком ранний сбор. Глобальная ссылка сделала свое дело! Еще раз спасибо! - person Shockwaver; 29.12.2014