Reputation: 25673
I am trying to use a customized keyboard in my application, but I am hitting problems when trying to restrict it to one particular UITextField.
I based my code on this Xcode project (originally found on this blog). That code adds a custom UIButton (representing a 'decimal point') into the UIKeyboardTypeNumberPad keyboard view. It does it by subscribing to UIKeyboardWillShowNotification and modifying the keyboard when it appears.
That Xcode project works great, but when I add an extra UITextField, the custom key gets put into the keyboard for that text field too, even though I have selected a completely different keyboard type for that text field.
I attempted to register to only see UIKeyboardWillShowNotification notifications from the one particular UITextField, but that doesn't seem to work:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:exampleViewController.textField];
I also tried to inspect the object inside the NSNotification passed to keyboardWillShow, but unfortunately it refers to the keyboard, not the UI control that caused the keyboard to appear.
2009-10-21 19:50:22.205 Example[6302:207] NSConcreteNotification 0x321ebd0 {name = UIKeyboardWillShowNotification; userInfo = {
UIKeyboardAnimationCurveUserInfoKey = 0;
UIKeyboardAnimationDurationUserInfoKey = 0.300000011920929;
UIKeyboardBoundsUserInfoKey = NSRect: {{0, 0}, {320, 216}};
UIKeyboardCenterBeginUserInfoKey = NSPoint: {160, 588};
UIKeyboardCenterEndUserInfoKey = NSPoint: {160, 372};
}}
Am I misunderstanding the addObserver interface? Surely there must be a way to subscribe to notifications from a particular UI control?
Has anybody got any other suggestions on how to achieve this?
Upvotes: 15
Views: 12910
Reputation: 16149
A swift version of @berilcetin's answer.
extension UIView {
var firstResponder: UIView? {
if self.isFirstResponder {
return self
}
return getSubView(views: self.subviews)
}
private func getSubView(views: [UIView]) -> UIView? {
guard subviews.count > 0 else {
return nil
}
if let responder = views.filter({ $0.isFirstResponder }).first {
return responder
}
for responder in views {
if let view = getSubView(views: responder.subviews) {
return view
}
}
return .none
}
}
usage
yourView.firstResponder as? UITextField
.
if you are working on UITableViewCell
for cell in tableView.visibleCells {
if let view = cell.contentView.firstResponder as? UITextField {
// view ...
break
}
}
Upvotes: 0
Reputation: 318
You can write a UIView category method to find the first responder.
- (UIView *)firstResponder
{
if ([self isFirstResponder])
{
return self;
}
for (UIView *view in self.subviews)
{
UIView *firstResponder= [view firstResponder];
if (firstResponder)
{
return firstResponder;
}
}
return nil;
}
Then in your - (void)keyboardWillShow:(NSNotification *)notification
method you can use it like this
UITextField *textField = (UITextField *)[self firstResponder];
Upvotes: 3
Reputation: 1023
Couldn't get any of the above to work. Had to do it manually:
if ([companyName isFirstResponder]) {
// ...............
}
else if ([notes isFirstResponder]) {
//.............
}
}
Upvotes: 25
Reputation: 96937
That project works great, but when I add an extra UITextField, the custom key gets put into the keyboard for that text field too.
You can set the keyboard type for a UITextField
instance, e.g.:
[myTextField setKeyboardType:UIKeyboardTypeDefault];
or:
myTextField.keyboardType = UIKeyboardTypeDefault;
Search the Xcode help on UITextInputTraits Protocol
for a list of UIKeyboardType
constants.
Upvotes: 0