Capture key press event using NSNotificationCenter - iphone

this solution
Receive iPhone keyboard events
offers a way to capture the keypress event using notification center.
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(keyPressed:) name: UITextFieldTextDidChangeNotification object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(keyPressed:) name: UITextViewTextDidChangeNotification object: nil];
........
-(void) keyPressed: (NSNotification*) notification
{
NSLog([[notification object]text]);
}
It works ok, but for every key that is been pressed from the keyboard the keyPressed function gets called 3 times.
Is this normal or am i doing something wrong?
Teo

The notification should only appear once per key pressed. At least that is what I get when testing. The only thing I can think of is that you are calling addObserver:selector:name:object: three times.
Perhaps you are doing it in several view controllers and forget to call removeObserver:name:object:?
Or you are calling addObserver:selector:name:object: in a function that gets called several times? viewDidLoad is normally a good place to put code like this.

Related

Execute code after method has finished

I need to execute some code after I know the keyboard is hidden.
Ive been looking in to blocks but I'm just not understanding how they work enough to do this...
All I want to do is run [self hidekeyboard] then when that is complete (and the keyboard fully hidden) then I want to call a delegate.
What is the best way to handle this and how?
You want to use the UIKeyboardDidHide notification and run your code in there. Here is the link in the docs...
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(onKeyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];
And the onKeyboardDidHide:
-(void)onKeyboardDidHide:(NSNotification *)notification
{
// execute what you want.
}
Register a listener for the UIKeyboardDidHideNotification using the NSNotificationCenter class.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(keyboardHidden:)
name:UIKeyboardDidHideNorification
object:nil];
- (void)keyboardHidden:(NSNotification *)notif
{
// do stuff
}
(Don't forget to remove the observer in - dealloc so that no messages will erroneously be sent to deallocated objects.)
You probably want to register to receive notifications of UIKeyboardDidHideNotification.
http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

addObserver: name

I'm using an addObserver like so:
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(notificationReceived:) name:nil object: nil];
Everything works well, but I thought it might be good form to remove the observer when I no longer needed it... I found that I needed to use this line:
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"observerName" object:nil];
Problem is, when I change my addObserver line to include the name so that the removeObserver will know which observer to remove, the notifications no longer get called. This line is run but ignored when the name is added:
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(notificationReceived:) name:#"observerName" object: nil];
I can set the name back to nil and it works again.
Anybody know what I'm doing wrong here?
Thanks!
I think you might be mistaken as the what the parameters mean.
The name: tells the system which notifications you want to be informed about.
self is the actual observer, so when you removeOberserver:self you will stop to receive any notifications.
You should read the documentation carefully again as to which have which meaning:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html#//apple_ref/doc/uid/20000219-SW1
For an example, see How to create a class to send and receive events through NSNotificationCenter in Objective-C?

send application delegate message to current view without notification center

I want to display application delegate message such as "Application became active" (This is called when -applicationDidBecomeActive:application is called)
on Window.
One way is to use notification center like below:
AppDelegate.m
NSNotification *n = [NSNotification notificationWithName:#"AppBecameActive" object:self];
[[NSNotificationCenter defaultCenter] postNotification:n];
ViewController.m
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:#selector(showMessageAppBecameActive) name:#"AppBecameActive" object:nil];
This way is only way to show application delegate message ? Or, is there any other way such as property to look current view controller instance ?
Thank you for your kindness.
If you have access to the ViewController from your appDelegate. (I mean like #property or instance is reside in it) you can straight away send a message. If you do not have such access to it. write key value observer for a single ton and let your viewController receive the change.
Register below code in your viewController which wants notification.
[[NSNotificationCenter defaultCenter]addObserver:self
selector:#selector(yourMethod)
name:UIApplicationDidBecomeActiveNotification
object:nil];
iOS framework posts a notification when your app become active, if you will register via above way, you can handle the notification in registered method (In this case yourMethod).

Performing an action on one view, and the action doing something on another view? Is this possible?

I have 2 views:
OneViewController
TwoViewController
TwoViewController has an IBAction which plays a sound. Once the user has pressed the button on TWoViewController I want a UILabel which will appear on OneViewController saying that the sound has been played.
Thanks for the help
All you have to do is reference one viewController in the other one, that way you can call it's methods. Or you can simply create a delegate.
One possible solution is to use notifications.
In the action that plays a sound, post a notification to the default notification center that indicates the sound has played.
[[NSNotificationCenter defaultCenter] postNotificationName:"playSoundNotification"
object:self
userInfo:nil];
When OneViewController is created, have it register for the notification.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(showPlayedLabel:)
name:"playSoundNotification"
object:nil];
When it receives the notification -- in showPlayedLabel: -- display the UILabel. Note that showPlayedLabel must follow the appropriate signature format.
- (void) showPlayedLabel:(NSNotification*) aNotification;

Unknown iphone code

I am looking at a project which was provided me by my organization, for study.
The problem is that in this project I found some code which I never saw before.
Please tell me why the following code is written.
-(void)notifications
{
[[NSNotificationCenter defaultCenter] addObserver: self selector:
#selector(hideViews) name: #"Hide" object:nil];
}
This problem arose because this project has only some code for designing.
Sorry if this is a silly question...
You should read up on how notifications work in Cocoa. Consult Apple's documentation for more information: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html
Basically, NSNotificationCenter is a class that broadcasts NSNotifications from one object to potentially many observing objects. One object can post a notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"NotificationName" object:self];
and other objects can listen for this notification.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationHandler:) object:theObjectThatPostedTheNotification];
Then, when the first object posts the notification, NSNotificationCenter will notify the other observing object, and notificationHandler: gets called.