1
votes

I have a class that makes a keyboard toolbar which has "Next", "Previous", and "Done" buttons on it. Is there a way for this class to know (or find out) what objects are on the screen at any time?

E.g., can it see what the current view is and what the text fields on it are, and then be able to resign the first responder?

4

4 Answers

1
votes

If you specifically want to resign first responder without the need to known which view is the first responder you can send resignFirstResponder to "nil" like this:

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

This is documented behaviour although I cannot find in the docs right now.

0
votes

Is there a way for this class to know (or find out) what objects are on the screen at the time?

Find the momma view and you can iterate through all the objects on the screen (because they will be UIViews too) like this. Note that you may need to add recursion:

for (UIView *view in mommaView.subviews) {
    do something to the view
}
0
votes

You can start at the Window class and go down from there, asking [view respondsTo:@selector(isFirstResponder) && [view isFirstResponder] on each. Some debugging code that I use might come in handy as a template and also while debugging:

+ (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, @"");
}
0
votes

yes, the methods provided below will be called whenever a textField becomes Active. I think you are looking for

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

or

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

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

and if you are looking for a specific textField in your view, you should assign them tags:

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

// You may check for these tags and then resign specific ones.