I found a curious difference in behavior running my app on an iOS4 device vs.
running the same app on an iOS5 device. On iOS4, if I set a view (or really
just a UIResponder) to be firstResponder, and then later, resignFirstResponder,
there is no defined firstResponder; whatever was firstResponder previously is
clobbered. Our app needed a more defined approach to this, so when a new
firstResponder was being set, we attempt to iterate through all views to find
and cache any existing firstResponder so we could restore it when our new
firstResponder resigned its firstResponder status. I have found that on iOS
5, this seems to happen automatically: becomeFirstResponder seems to cache any
existing firstResponder and resignFirstResponder restores the cached
responder's firstResponder status. I can't find any Apple documentation that
addresses this behavior at all.
Is this behavior that can be relied upon? My reading of the UIResponder
documentation is that I shouldn't rely on the state of the current
firstResponder, and that if my app needs a specific view to be firstResponder
at a particular point in time, it should set it explicitly. On the other hand,
trying to determine the current firstResponder is clunky with current API's,
and if Apple's doing it for me, I'd rather let them do it.
I realize iOS 4 is ancient history at this point, though my app still needs to
support it. (I also have no idea what the behavior is on iOS 6.)
Below is some sample code that illustrates the different behavior:
@interface testResponder : UIResponder
@end
@implementation testResponder
- (UIResponder*)nextResponder
{
return [UIApplication sharedApplication].keyWindow.rootViewController;
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
@end
@implementation ViewController
-(BOOL) canBecomeFirstResponder
{
return YES;
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self becomeFirstResponder];
NSLog(@"View controller is now %@", ([self isFirstResponder] ?
@"FirstResponder" : @"NOT First Responder!"));
testResponder *newResponder = [[testResponder alloc] init];
[newResponder becomeFirstResponder];
NSLog(@"View controller is now %@", ([self isFirstResponder] ?
@"FirstResponder" : @"NOT First Responder!"));
[newResponder resignFirstResponder];
NSLog(@"View controller is now %@\n\n\n", ([self isFirstResponder] ?
@"FirstResponder" : @"NOT First Responder!"));
[newResponder release];
}
@end
Output on iOS4:
2013-01-07 12:45:44.999 testFirstResponderTwo[835:607] View controller is now
FirstResponder
2013-01-07 12:45:45.007 testFirstResponderTwo[835:607] View controller is now
NOT First Responder!
2013-01-07 12:45:45.010 testFirstResponderTwo[835:607] View controller is now
NOT First Responder!
Output on iOS5:
2013-01-07 12:42:57.858 testFirstResponderTwo[1886:707] View controller is now
FirstResponder
2013-01-07 12:42:57.862 testFirstResponderTwo[1886:707] View controller is now
NOT First Responder!
2013-01-07 12:42:57.865 testFirstResponderTwo[1886:707] View controller is now
FirstResponder
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]