'Find View that is the firstresponder
I would like to get the view that is the first responder, currently I have a UITableView that contains UITextFields, using a method:
-(UIView*) findFirstResponder
{
}
I would like to be able to get the view that is the firstResponder and then do something with that view.
Any ideas?
Solution 1:[1]
Use UIControl as a root reference to different types of control that can become first responder.
UIControl *currentControl;
As Gobot says - whenever a textfield becomes first responder, keep a note of which one it is...
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
currentControl = textField;
. . .
Solution 2:[2]
There is no simple way to find firstResponder
in iOS. The answers above are only tracking UIView
s but all subclasses of UIResponder
such as UIViewController
can be a first responder.
According to the Quick Help
of UIResponder
:
Many key objects are also responders, including the UIApplication object, UIViewController objects, and all UIView objects (which includes UIWindow). As events occur, UIKit dispatches them to your app's responder objects for handling.
And the only way to follow UIResponder
chain will be using UIResponder
's next: UIResponder
property.
Returns the next responder in the responder chain, or nil if there is no next responder. The UIResponder class does not store or set the next responder automatically, so this method returns nil by default. Subclasses must override this method and return an appropriate next responder. For example, UIView implements this method and returns the UIViewController object that manages it (if it has one) or its superview (if it doesn’t). UIViewController similarly implements the method and returns its view’s superview. UIWindow returns the application object. UIApplication returns nil.
In the most UIKit
object superview
, UIViewController
, UIWindow
, UIApplication
or Appdelegate
will be the next
UIResponder
.
extension UIResponder {
func findFirstResponder() -> UIResponder? {
var responder: UIResponder? = self
while responder != nil {
guard let r = responder, r.isFirstResponder else {
responder = responder?.next
continue
}
return r
}
return nil
}
}
However the above doesn't track responder
's siblings. I guess if you really want to track them all, you need to check the type of responder and track its child(subview, child view controller).
Solution 3:[3]
I would like to shared with you my implementation for find first responder in anywhere of UIView. I hope it helps and sorry for my english. Thanks
+ (UIView *) findFirstResponder:(UIView *) _view {
if ([subView isFirstResponder])
return subView;
if ([subView isKindOfClass:[UIView class]]) {
UIView *v = subView;
if ([v.subviews count] > 0) {
retorno = [self findFirstResponder:v];
if ([retorno isFirstResponder]) {
return retorno;
}
}
}
}
Solution 4:[4]
We can take advantage of the fact that calling UIApplication.shared.sendAction
with a target of nil
sends the action to the first responder.
Swift
extension UIResponder {
private static weak var _firstResponder: UIResponder?
static var firstResponder: UIResponder? {
_firstResponder = nil
// Tell the first responder to record itself in `_firstResponder`
UIApplication.shared.sendAction(#selector(_recordFirstResponder), to: nil, from: nil, for: nil)
return _firstResponder
}
@objc private func _recordFirstResponder() {
UIResponder._firstResponder = self
}
}
Then simply accessing UIResponder.firstReponder
will give us the first responder.
Objective-C
static __weak id foundFirstResponder;
@implementation UIResponder (FindFirstResponder)
+(id)firstResponder {
foundFirstResponder = nil;
[UIApplication.sharedApplication sendAction:@selector(findFirstResponder) to:nil from:nil forEvent:nil];
return foundFirstResponder;
}
-(void)findFirstResponder {
foundFirstResponder = self;
}
@end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ilias Karim |
Solution 3 | Rubens Iotti |
Solution 4 | McKinley |