Почему вызов [self сталFirstResponder] вызвал так много проблем? - PullRequest
4 голосов
/ 14 октября 2011

В последние несколько дней моей жизни я очень старался понять, что со мной не так.На определенной странице, если я добавлю UITextViews, или UITextFields, или MFMailComposer, или MessageComposer, или что-то еще с полями, требующими редактирования, поля просто не будут реагировать на прикосновения.Я не мог ничего редактировать, когда я запустил приложение.Я не мог редактировать текстовые представления или поля электронной почты или что-нибудь.Я перепробовал все, но ничего не получалось.Оказывается, что на главной странице (MainVC), которая ведет на страницу, где поля не отвечают (GiftVC), в методе viewDidAppearMainVC) я говорю: [self becomeFirstResponder];,

Теперь я не совсем уверен, почему я это написал, но оказывается, что комментирование этой строки исправляет все и заставляет все поля, текстовые представления и составители писем, и все снова работает нормально.

У меня также есть это на странице MainVC:

-(BOOL)canBecomeFirstResponder {
    return YES;
}

, и комментирование этого также решает проблему.

Странная часть в том, что даже с[self becomeFirstResponder], в новой iOS 5 (симулятор и устройство) все работало просто отлично, но в iOS 4 (симулятор и устройство) она вообще не работала с этой линией.Теперь, когда я удалил его, он отлично работает в обоих случаях.

Ответы [ 4 ]

4 голосов
/ 03 декабря 2011

Если в вашем подклассе UIViewController есть следующее

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.view.window) {
        [self becomeFirstResponder];
    }
}

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

Если вы не смогли отредактировать UITextField s, то этот подкласс, вероятно, стал первым респондентом и не перенаправил событие фактическому UITextField. Когда подкласс UIViewController вызывает переопределения canBecomeFirstResponder для возврата YES и делает их самостоятельно первым респондентом (т. Е. [self becomeFirstResponder], если вы не хотите, чтобы этот пользовательский класс обрабатывал события касания для UITextField, тогда вы должны переопределить метод nextResponder.

Пример из моего собственного продукта. По сути, у меня есть подкласс UIViewController, который выполняет две вещи: 1) обрабатывает события встряхивания и 2) отображает другой вид модально при нажатии какой-либо кнопки. На модальном виде есть несколько UITextField с. Чтобы мой подкласс UIViewController мог перенаправить сенсорные события в мой модальный вид, я добавил следующее:

- (UIResponder *)nextResponder
{
    if (!self.view.window) {
        // If the modal view is being displayed, forward events to it.
        return self.modalViewController;
    } else {
        // Allow the superclass to handle event.
        return [super nextResponder];
    }
}

Это будет работать на iOS 4 и 5 с любым sdk.

Теперь, в вашем случае вы, очевидно, не помните, что добавили код, чтобы стать первым респондентом, поэтому вам не нужны вышеуказанные хуки. Тем не менее, это хорошо знать на будущее.

Возвращаясь к вашему актуальному вопросу - после того, как вы обновили свой SDK до 5, почему бы не работать на iOS 4, а на iOS 5? iOS 5 делает некоторые пересылки событий для вас, поэтому он работает там. Сначала он никогда не работал на iOS 4. Apple исправила некоторые ошибки, которые позволяли ему работать на 4, поэтому он больше не работает на 4.

Я знаю, что вопрос уже принял принятый ответ; Я просто хотел прояснить ситуацию.

3 голосов
/ 14 октября 2011

Проверьте, есть ли в MainVC метод с именем canResignFirstResponder, который возвращает NO (по крайней мере, иногда). Если это так, то, как только он станет первым респондентом, он не позволит никому другому стать первым респондентом, пока не вернет ДА ​​из этого метода. (Все UITextViews и т. Д. Должны стать первым респондентом для редактирования.)

На самом деле просто посмотрите везде во всем вашем коде на canResignFirstResponder, на случай, если он в суперклассе или что-то в этом роде.

В противном случае единственное, что помешало бы редактированию текстовых полей и представлений, вероятно, было бы, если бы они получили set userInteractionEnabled = NO, но, поскольку он зависит от оператора становитсяFirstResponder, это, скорее всего, связано с canResignFirstResponder.

2 голосов
/ 14 октября 2011

В iOS 4 подкласс должен переопределить canBecomeFirstResponder, чтобы иметь возможность стать первым респондентом.Может быть, это отличается для iOS 5 или это ошибка.

1 голос
/ 08 ноября 2013

Попробуйте, убедитесь, что вы добавили uiTextViewDelegate и

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
    NSLog(@"textViewShouldBeginEditing:");
    return YES;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...