Уволить первого респондента из отдельного класса

У меня есть класс, который создает панель инструментов клавиатуры, на которой есть кнопки «Далее», «Назад» и «Готово». Есть ли у этого класса способ узнать (или выяснить), какие объекты находятся на экране в любое время?

Например, может ли он видеть текущее представление и текстовые поля в нем, а затем иметь возможность уволить первого респондента?


person Darc    schedule 18.06.2011    source источник


Ответы (4)


Есть ли у этого класса способ узнать (или выяснить), какие объекты находятся на экране в данный момент?

Найдите представление мамы, и вы можете перебирать все объекты на экране (потому что они тоже будут UIViews), как это. Обратите внимание, что вам может потребоваться добавить рекурсию:

for (UIView *view in mommaView.subviews) {
    do something to the view
}
person Richard Brightwell    schedule 18.06.2011

Если вы специально хотите уволить первого респондента без необходимости знать, какое представление является первым респондентом, вы можете отправить resignFirstResponder как «nil» следующим образом:

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

Это задокументированное поведение, хотя я не могу найти в документации прямо сейчас.

person Nicolai Henriksen    schedule 29.02.2016

Вы можете начать с класса Window и спуститься оттуда, задавая [view responseTo: @selector (isFirstResponder) && [view isFirstResponder]] для каждого из них. Некоторый отладочный код, который я использую, может пригодиться в качестве шаблона, а также при отладке:

+ (void) dumpWindowFrom:(NSString *) fromText {
    [self dumpViews:[[UIApplication sharedApplication] keyWindow] from:fromText];
}

void dumpViewsRecursive(UIView* view, NSString *text, NSString *indent) 
{
    Class cl = [view class];
    NSString *classDescription = [cl description];
    //  while ([cl superclass])   //restore to print superclass list
    //  {
    //      cl = [cl superclass];
    //      classDescription = [classDescription stringByAppendingFormat:@":%@", [cl description]];
    //  }

    if ([text compare:@""] == NSOrderedSame)
        NSLog(@"%d: %@ %@ %@", (int)view, classDescription, NSStringFromCGRect(view.frame), view.hidden ? @"Inv" : @"Vis");
    else
        NSLog(@"%d: %@ %@ %@ %@", (int)view, text, classDescription, NSStringFromCGRect(view.frame), view.hidden ? @"Inv" : @"Vis");

    for (NSUInteger i = 0; i < [view.subviews count]; i++)
    {
        UIView *subView = [view.subviews objectAtIndex:i];
        NSString *newIndent = [[NSString alloc] initWithFormat:@"  %@", indent];
        NSString *msg = [[NSString alloc] initWithFormat:@"%@%d:", newIndent, i];
        dumpViewsRecursive (subView, msg, newIndent);
        [msg release];
        [newIndent release];
    }
}

+ (void) dumpViews: (UIView *) view {
    dumpViewsRecursive  (( (!view) ? [[UIApplication sharedApplication] keyWindow] : view), @"" ,@"");
}

+ (void) dumpViews: (UIView *) view from:(NSString *) fromText{
    dumpViewsRecursive ((!view) ? [[UIApplication sharedApplication] keyWindow] : view, fromText, @"");
}
person mackworth    schedule 18.06.2011

да, методы, представленные ниже, будут вызываться всякий раз, когда textField становится активным. Я думаю ты ищешь

- (BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return 1;
}

or

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
}

- (void) textFieldDidEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
}

и если вы ищете конкретное текстовое поле в своем представлении, вам следует назначить им теги:

textField.tag =1 // for textField 1
textField.tag =2 // for textField 2

// You may check for these tags and then resign specific ones. 
person Legolas    schedule 18.06.2011