I trying to show a keyboard when pressing on UILabel using NotificationCenter but the keyboard function is not calling and not showing the keyboard, I really need to show a keyboard appear when pressing on UILabel in Swift.
inside my class
MyClass : UIControl {}
but the keyboard function is not calling
private func _ini(){ let notificationCenter = NotificationCenter.default notificationCenter.addObserver(self, selector: #selector(KeyboardDidShow(_:)), name: UIResponder.keyboardDidShowNotification, object: nil) }
func KeyboardDidShow( myNotification: NSNotification){
print("keyBoardUp")
}
Keyboard only shows up for views which accept inputs e.g. UITextField, UITextview etc or the views which confirm to follow UIKeyInput protocol and implement canBecomeFirstResponder
Related
I create multiple UITextFields in my storyboard. Some text field are edited using keyboard while others using picker view. In my view controller, for the fields using pickerView, I created separate picker views for each of the text fields. For eg.
aTextField.inputView = aPickerView
Now for the text fields which are at the bottom of the screen, when I tap on one of them, picker view corresponding to that text field opens at the bottom and it hides the textfield. I want to shift the currently selected text field up when the picker view opens.
In case of keyboard, shifting of views can be done by responding to UIResponder.keyboardWillShowNotification. How to do this in case of picker view?
One solution that I can think of is observing keyboard height. When you press the picker view that has to show up the bottom textField, use keyboard height and some extra points to move it over the keyboard. Here are some helper methods to achieve that:
override func viewDidLoad() {
super.viewDidLoad()
// Add keyboard observers
addObservers()
}
private func addObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
// keyboard will be active
#objc private func keyboardWillShow(notification: NSNotification) {
// Get keyboard Size
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
// update constraints / footerview height with keyboard height "keyboardSize.height"
}
}
// keyboard will dismiss
#objc private func keyboardWillHide(notification: NSNotification) {
if (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue != nil {
// update constraints / footerview height when keyboard is hidden,
}
}
I currently have a table-view with a textfield acting as a search bar above it. I have the tableview set in interface builder to dismiss the keyboard onDrag. However, whenever I drag down the tableView reloads its data. How can I prevent this?
You could use the keyboard events to enable and disable user interaction on the table, to do this you must register keyboard observers as said in the answer of this question by Jitendra Solanki: iOS Swift detect keyboard events
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil)
And use the callbacks functions to enable and disable the user interaction
func keyBoardWillShow(notification: NSNotification) {
tableView.userInteractionEnabled = NO;
}
func keyBoardWillHide(notification: NSNotification) {
tableView.userInteractionEnabled = YES;
}
But instead ofthe keyboardWillHide, you could use your event of hidekeyboard to reactivate the user interaction.
When a user taps on a button, I'd like the keyboard to pop up (which is easy), but I want a view that goes up along with it (sticking to the top of the keyboard). This view will be have a "send a message.." textfield. When the user pushes done, I want the keyboard to go away along with the view.
How do I make this view "stick" to the keyboard?
UITextFields have a property called inputAccessoryView
- Apple Documentation
- Relevant Stack Overflow Answer
This will pin whatever view you assign as that textfield's inputAccessoryView to the top of the keyboard.
Something important from the answer in that link to remember:
Note that the view you use should neither be in the view hierarchy elsewhere, nor should you add it to some superview, this is done for you.
go to your storyboard and add a view(lets call it topKeyboardView) at the bottom of your viewController. and give it the following constraints:
bottom space to bottom layout = 0
and then add the textfield*(i prefer using textView to make it change its height when the message gets too long...)*
and your button(send) on top of topKeyboardView.
lets code now..
go to your viewController.swift and add an IBOutlet to your textField and button and add this function:
//this is will tell if the keyboard hidden or not
func addKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
}
// MARK:- Notification
func keyboardWillShow(notification: NSNotification) {
print("keyboard is up")
}
func keyboardWillHide(notification: NSNotification) {
print("keyboard is down")
}
in your viewDidLoad call the function:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
addKeyboardNotifications()
}
run it...
When a user taps on a button, I'd like the keyboard to pop up (which is easy), but I want a view that goes up along with it (sticking to the top of the keyboard). This view will be have a "send a message.." textfield. When the user pushes done, I want the keyboard to go away along with the view.
How do I make this view "stick" to the keyboard?
UITextFields have a property called inputAccessoryView
- Apple Documentation
- Relevant Stack Overflow Answer
This will pin whatever view you assign as that textfield's inputAccessoryView to the top of the keyboard.
Something important from the answer in that link to remember:
Note that the view you use should neither be in the view hierarchy elsewhere, nor should you add it to some superview, this is done for you.
go to your storyboard and add a view(lets call it topKeyboardView) at the bottom of your viewController. and give it the following constraints:
bottom space to bottom layout = 0
and then add the textfield*(i prefer using textView to make it change its height when the message gets too long...)*
and your button(send) on top of topKeyboardView.
lets code now..
go to your viewController.swift and add an IBOutlet to your textField and button and add this function:
//this is will tell if the keyboard hidden or not
func addKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
}
// MARK:- Notification
func keyboardWillShow(notification: NSNotification) {
print("keyboard is up")
}
func keyboardWillHide(notification: NSNotification) {
print("keyboard is down")
}
in your viewDidLoad call the function:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
addKeyboardNotifications()
}
run it...
I have a UITextfield with an inputView of PickerView. I want to achieve that when users double tap on the UITextfield, the pickerView shows up modally, like default, and the focus of accessibility changes from the textfield to the pickerView. This is how I do it for now:
func textFieldDidBeginEditing(textField: UITextField) {
let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.65 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.quantityPicker)})
}
This delegate simply gets called when user double taps the textField and send a UIAccessibilityLayoutChangedNotification after a delay of 0.65 seconds to focus on pickerView.
Then questions are:
I used a delay here to wait for the pickerView pop-up animation to be done, but it will be much better if I can know that pickerView animation is done somewhere and put
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.quantityPicker)
there. So is there any delegate or other simple way to know that pickerView is ready to use?
When I double tap the textField, it will read the content of the textField first until it gets intercepted. Is there anyway to disable this to make it like: when I single tap the button, read accessibilityLabel, trait, hints etc, and when I double tap it, it reads nothing and just does its job.
You can use notification centre event UIKeyboardDidShowNotification. In the view controller hosting the UITextField add code to viewWillAppear method:
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(self.keyboardDidShow(_:)),
name: UIKeyboardDidShowNotification,
object: nil)
In the viewWillDisappear method add:
NSNotificationCenter.defaultCenter().removeObserver(self)
Then add a method keyboardDidShow:
func keyboardDidShow(notification:NSNotification) {
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.quantityPicker)
}
Of course if you have other input fields in your view controller you'll need to add some conditional code to keyboardDidShow.
Tested and working. Thanks for the question, I've been chasing the same issue.
If you present the view as part of a separate modal view controller, you can use the viewDidAppear method as the callback you are looking for.
-(void)viewDidAppear:(BOOL)animated {
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, outletOfViewYouWantFocused);
}
#Dale's answer in Swift 4:
viewWillAppear
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow(notification:)), name: UIResponder.keyboardDidShowNotification, object: nil)
viewWillDisappear
NotificationCenter.default.removeObserver(self)
keyboardDidShow
#objc func keyboardDidShow(notification: Notification) {
UIAccessibility.post(notification: .layoutChanged, argument: self.quantityPicker)
}