Not getting Keyboard Hide notification - objective-c

I am noticing that after I register for the UIKeyboardWillHideNotification notification, I do not get the callback keyboardDisappeared:(NSNotification*)note
I am trying to hit the "down keyboard button" on my keyboard but nothing is firing.
This is how I register:
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(keyboardDisappeared:) name:UIKeyboardWillHideNotification object:self];
And this is my callback:
- (void)keyboardDisappeared:(NSNotification*)note
{
NSLog#("called");
}
Also this method :
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
is not getting called. But this one:
- (void)textViewDidBeginEditing:(UITextView *)textView
IS getting called...
Any thoughts or suggestions?
Thanks,

You need to implement the UITextField delegate method, textFieldShouldReturn:, and have your text field resign first responder status in that method.

Related

How to find out that keyboard down arrow key pressed, programmatically

I know that when down arrow key is pressed on keyboard then we can get Keyboard Hide notification but the problem is, we get Keyboard Hide notification also when we rotate the device and keyboard hides, now how to differentiate that keyboard is hiding because of key pressed not because of rotation.
In your AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(keyboardWillHide)
name:UIKeyboardWillHideNotification object:nil];
return YES;
}
-(void) keyboardWillHide {
NSLog(#"Bye");
}
Following Delegate method of textfield is called automatically when we clicked on the return or arrow button of keyboard.
- (BOOL)textFieldShouldReturn:(UITextField *)textField

Detecting a change to text in UITextfield

I would like to be able to detect if some text is changed in a UITextField so that I can then enable a UIButton to save the changes.
Instead of observing notifications or implementing textField:shouldChangeCharacterInRange:replacementString:, it's easier to just add an event target:
[textField addTarget:self
action:#selector(myTextFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
- (void)myTextFieldDidChange:(id)sender {
// Handle change.
}
Note that the event is UIControlEventEditingChanged and not UIControlEventValueChanged!
The advantages over the other two suggested solutions are:
You don't need to remember to unregister your controller with the NSNotificationCenter.
The event handler is called after the change has been made which means textField.text contains the text the user actually entered. The textField:shouldChangeCharacterInRange:replacementString: delegate method is called before the changes have been applied, so textField.text does not yet give you the text the user just entered – you'd have to apply the change yourself first.
Take advantage of the UITextFieldTextDidChange notification or set a delegate on the text field and watch for textField:shouldChangeCharactersInRange:replacementString.
If you want to watch for changes with a notification, you'll need something like this in your code to register for the notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldDidChange:) name:UITextFieldTextDidChangeNotification object:theTextField];
Here theTextField is the instance of UITextField that you want to watch. The class of which self is an instance in the code above must then implement textFieldDidChange, like so:
- (void)textFieldDidChange:(NSNotification *)notification {
// Do whatever you like to respond to text changes here.
}
If the text field is going to outlive the observer, then you must deregister for notifications in the observer's dealloc method. Actually it's a good idea to do this even if the text field does not outlive the observer.
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Other dealloc work
}
For that, first you need to have your textfield have it delegate reference assigned. And the delgate, should preferably be, the vew controller which is the files owner of the view.
Which goes like
myTextField.delegate = myViewControllerReferenceVariable
And in your viewController interface, tell you will be implementing UITextFieldDelegate by
#interface MyViewController:UIViewController<UITextFieldDelegate>
And in your view controller implementation override
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
So the code will look like
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
text = [textfield.text stringByReplacingCharactersInRange:range withString:string];
if (textfield == refToTextFieldYouWantToCheck) {
if ( ! [textToCheck isEqualToString:text] ) {
[theButtonRef setEnabled:YES];
}
}
return YES; //If you don't your textfield won't get any text in it
}
You can also subscribe to notification which is sort of messy IMHO
You can find how to do it here.
Swift 3.0
Process 1
Create IBOutlet of UITextfiled and Add Target to text field.
m_lblTxt.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControlEvents.editingChanged)
func textFieldDidChange(textField:UITextField)
{
NSLog(textField.text!)
}
Process 2
m_lblTxt.delegate = self
//MARK: - TextField Delegates
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
print(textField.text!)
return true
}
This can be accomplished in Interface Builder on the Editing Changed event of UITextField. Drag from it to your code and create an IBAction.
For example:
#IBAction func textFieldChanged(_ sender: UITextField) {
print(sender.text)
}
This event is the same as described in other answers here in that the .text property contains the updated text input when it gets triggered. This can help clean up code clutter by not having to programmatically add the event to every UITextField in the view.
You could create a variable to store the original string, then register with the notification center to receive UITextFieldTextDidChangeNotification event:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateButton:) name:UITextFieldTextDidChangeNotification object:nil];
Then, create a method to receive the notification, and compare the current value of the text field with the original value
-(void) updateButton:(NSNotification *)notification {
self.myButton.enabled = ![self.myTextField.text isEqualToString:originalString];
}
Don't forget to de-register the notification when the view controller is deallocated.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
You can add a class member like this NSString *changeTemp,then
changetemp = textfield;
if( change temp != textfild ){
changetemp=textfild;
NSLog(#" text is changed"
} else {
NSLog(#" text isn't changed"):
}

NSWindow is not receiving any notification when it loses focus

I have a custom NSWindow class that has the following methods:
- (void)setupWindowForEvents{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidResignKey:) name:NSWindowDidResignMainNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:self];
}
-(void)windowDidResignKey:(NSNotification *)note {
NSLog(#"notification");
[self close];
}
I call [_window setupWindowForEvents]; but the windowDidResignKey never gets called.
This is how I call my NSWindow: when the status bar item is clicked I makeKeyAndOrderFront and the Window is displayed right beneath the status bar item, like this:
Any ideas why the I don't get any notification when the window loses focus? I've used both NSWindowDidResignMainNotification and NSWindowDidResignKeyNotification to see if any of these worked, but none is working.
You're probably not getting the notification because you actually are never key in the first place. Your window appears to be borderless, and borderless windows don't grab key window status by default.
In your window subclass, be sure to return YES on the following methods:
- (BOOL)canBecomeKeyWindow {
return YES;
}
- (BOOL)canBecomeMainWindow {
return YES;
}

Calling UIKeyboard method on UITextView and not UITextFields

I have view with a UITextView for comments on the bottom. Since its on the bottom of the page, whenever someone edits it, a method is called to shift the view of the page, so that you can still see the comment box. My problem is that the same method also gets called when user are editing UITextFields.
Here's what I have. First I declare a notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
Then the method itself
- (void)keyboardWillShow:(NSNotification *)notif{
...
}
My first thought was to add a condition, to check and see if the object was a TextView, and only then execute the code. But since I am not passing the object to the method, is there anyway to tell the method what type of object I am dealing with
Text fields and text views also send notifications. In the textFieldShouldBeginEditing and the textViewShouldBeginEditing implementations you could set a flag that you can read in your implementation of the keyboardWillShow method -- the keyboard notification is sent after the text field or text view notifications.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
self.sender = #"text field";
return YES;
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
self.sender = #"text view";
return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
}
- (void)keyboardWillShow:(NSNotification *)notif{
NSLog(#"%#",self.sender);
}

Remove the "Dismiss keybard" key from a UITextView's keyboard on iPad

I have a modal view that with a UITextView, and the user can enter some text (or not) and close the modal view. There is no point of dismissing the keyboard as it does not dismiss the modal view (this is on purpose), and the UITextView without the keyboard just looks silly.
Is there a way to hide or remove the "Dismiss keyboard" key from the keyboard?
You can't hide or remove the key, but you can disable it using the UITextViewDelegate protocol:
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
return NO;
}
If UIKit forces the responder to resign despite the delegate (doubtful, but I haven't looked closely at the call stack), you can force the keyboard to stay up by observing the UIKeyboardDidHideNotification and setting the first responder back to the UITextView: [myUITextView becomeFirstResponder]
Protocol method doesn't help.
As Answerbot suggested one should listen to keyboard notification.
- (void)onIpadViewWillAppear
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showIpadKeyboard) name:UIKeyboardDidHideNotification object:nil];
}
- (void)onIpadViewWillDisappear
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)showIpadKeyboard
{
[myTextField becomeFirstResponder];
}
This works and looks beautifully.