Custom UIView and becomeFirstResponder - objective-c

I have a custom UIView that implements the UIKeyInput protocol and has
- (BOOL) canBecomeFirstResponder{
return YES;
}
defined in the subclass. When calling:
[customView becomeFirstResponder];
NSLog(#"is first? %i",[customView isFirstResponder]);
during a button click, it returns false, even though canBecomeFirstResponder is properly set and all of the UIKeyInput protocol functions are implemented. What other things could be blocking this view from becoming the first responder? It lives inside of a scrollView and another custom view if that helps.
Update:
I checked to see what the current first responder was with:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:#selector(firstResponder)];
and surprisingly firstResponder was nil. So nothing seems to be hogging the events.

Did you override becomeFirstResponder?
Subclasses can override this method to update state or perform some
action such as highlighting the selection.
Followup:
Subclasses can override this method to update state or
perform some action such as highlighting the selection.
A responder object only becomes the first responder if the current
responder can resign first-responder status (canResignFirstResponder)
and the new responder can become first responder.
You may call this method to make a responder object such as a view the
first responder. However, you should only call it on that view if it
is part of a view hierarchy. If the view’s window property holds a
UIWindow object, it has been installed in a view hierarchy; if it
returns nil, the view is detached from any hierarchy.
Did you verify you meet all of the above conditions?

Related

UIView isFirstResponder method always return no

In my viewController viewDidload() method isFirstResponder always giving false value. Here is the
code
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"is first responder : %i", [self.view isFirstResponder]);
}
Can someone please help why this happening?
Subclasses can override this method to update state or perform some action such as highlighting
the selection.
A responder object only becomes the first responder if the current responder can resign first-
responder status (canResignFirstResponder) and the new responder can become first responder.
You may call this method to make a responder object such as a view the first responder. However,
you should only call it on that view if it is part of a view hierarchy. If the view’s window
property holds a UIWindow object, it has been installed in a view hierarchy; if it returns nil,
the view is detached from any hierarchy.
Here is Apple doc

NSTextField is first responder but I still must click inside the text box before typing

My ultimate goal is to have an NSTextField selected by default allowing the user to start typing without clicking on the text field first.
I have a view controlled by a NSViewController. The view contains several text fields. The NSView and NSWindow are both custom subclasses. The text field is not subclassed. Just a standard NSTextField.
Inside awakeFromNIB for the view controller I have the code:
[[[NSApplication sharedApplication] mainWindow] makeFirstResponder:firstBox];
NSLog(#"%#",NSStringFromClass([[[[NSApplication sharedApplication] mainWindow] firstResponder] class]));
The text field gets a focus ring around it, and the NSLog prints that the first responder is an NSTextField but I still have to click inside the text field before I can begin typing.
What could cause the field to be the first responder but not editable? Is there a better method I should be calling makeFirstResponder from?
I found a potentially useful hint on CocoaDev.com, try doing this:
[[[NSApplication sharedApplication] mainWindow]
performSelector: #selector(makeFirstResponder:)
withObject: firstBox
afterDelay:0.0];

UIApplication sendEvent not working with popViewControllerAnimated

I'm trying to pop the current view controller from navigation controller. I want to do this from a subview that's buried pretty far down the view hierarchy. In my UIView subclass, I have a method:
- (void)back
{
NSLog(#"View should pop now...");
[[UIApplication sharedApplication] sendAction:#selector(popViewControllerAnimated)
to:nil
from:self
forEvent:nil];
}
But this doesn't work, nor does it throw any sort of error. What is going on here? Why does the action not progress up the responder chain like it's supposed to according to the documentation?
I recommend you use the notification center for this. Then the view hierarchy doesn't matter.
Or you could add the view controller as a target to the button.
Forgot to add the colon:
#selector(popViewControllerAnimated:)
Still, the behavior is very glitchy. Sometimes the transition is animated, sometimes it isn't and I'm not able to send popViewControllerAnimated's BOOL argument.

disable dismissal of uipopoverview controller

UIPopoverController automatically dismisses when we tap or touch outside the popoverview.
I want to restrict this automatic popover dismissal.
self.myPopovercontroller.passthroughViews=[NSArray arrayWithObject:self.view];
Duplicate of "is there a way NOT to have the popover dismissed when pressing outside it?"
There is a very simple and legit solution. In the view controller that presents your UIPopoverController, conform to the UIPopoverControllerDelegate protocol and implement the following delegate method. I just tested this and it does prevent popover to dismiss.
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
Just make sure that you have set the delegate of your popover controller to the view controller that implements this.
You can dismiss the popover by using [popoverController dismissPopoverAnimated:NO]; method.
Have a read of the UIPopoverController documentation. Specifically...
When displayed, taps outside of the popover window cause the popover
to be dismissed automatically. To allow the user to interact with the
specified views and not dismiss the popover, you can assign one or
more views to the passthroughViews property. Taps inside the popover
window do not automatically cause the popover to be dismissed. Your
view and view controller code must handle actions and events inside
the popover explicitly and call the dismissPopoverAnimated: method as
needed.
Implement popoverControllerShouldDismissPopover: in the delegate, and you can stop it from disappearing unless you want it to.

How does a UIView know about an added subview's UIViewController?

in the case of say
- (void)applicationDidFinishLaunching:(UIApplication *)application {
...
[window addSubview:gameController.view];
...
}
how does the view of gameController retain association to gameController? I've peaked through all of the Debugger variables and I see no association other than a boolean flag that it belongs to a view controller. so the view is passed along to a view hierarchy (wouldn't necessarily have to be off of window), yet gameController will get events such as shouldAutorotateToInterfaceOrientation . Where is this being kept track of if not as some tucked away reference in the UIView passed out of gameController.view
UIView *tmp = gameController.view;
[window addSubview:tmp];
Its obvious that gameController knows about tmp, but how does the window know about gameController after that code?
UIViewController is a descendant of UIResponder and is inserted into the responder chain between the view and that view's superview. So calling nextResponder on a view managed by a UIViewController will return said instance of UIViewController.
This is how events such as shouldAutorotateToInterfaceOrientation: get passed up through the hierarchy of instances of UIResponder. A diagram showing this can be seen in figure 3.1 in the iPhone Application Programming Guide.