In my custom UITableViewCell I added an observer in NSNotificationCenter:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(stopActivityIndicator) name:#"stopActivityIndicator" object:nil];
I post a notification in a UIViewController:
[[NSNotificationCenter defaultCenter] postNotificationName:#"stopActivityIndicator" object:nil];
This function "stopActivityIndicator" is not being called, any idea what causes this?
EDIT:
ExploreViewController.m
-(void)showCorrectBannerAfterPlusButtonClicked:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"stopActivityIndicator" object:nil];
}
ExploreViewController contains a UITableView with ExploreTableViewCells.
ExploreTableViewCell.m
- (IBAction)plusButtonClicked:(id)sender
{
self.plusButton.hidden = YES;
[self.plusButtonActivityIndicator startAnimating];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(stopActivityIndicator) name:#"stopActivityIndicator" object:nil];
}
-(void)stopActivityIndicator
{
_plusButton.hidden = NO;
[self.plusButtonActivityIndicator stopAnimating];
[[NSNotificationCenter defaultCenter]removeObserver:self name:#"stopActivityIndicator" object:nil];
}
Ok, question, when do you call "showCorrectBannerAfterPlusButtonClicked"?? As this is the method where you post the notification observed by the tableViewCell.
What I see is the notification observer adding and removal, but I don't see how the UIViewController knows when the cell's "plusButtonClicked" is called, so perhaps the method posting the notification is not being called.
Also, be careful with the cell reusage, have in mind if you should remove the observer at that point.
Related
NSNotification observers are added when awakeFromNib is called in my UITableViewCell. Then, I am removing the observers when removeFromSuperView is called.
- (void)awakeFromNib
{
[super awakeFromNib];
[self setNotificationObserver];
_vHolder.layer.cornerRadius = 10.0f;
_vHolder.layer.shadowColor = [UIColor blackColor].CGColor;
_vHolder.layer.shadowRadius = 2.0f;
_vHolder.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
_vHolder.layer.shadowOpacity = 0.5f;
}
- (void)removeFromSuperview
{
[super removeFromSuperview];
[self removeNotificationObserver];
}
- (void)setNotificationObserver
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didReceiveESSMQTTMessageNotification:) name:NOTIF_ESSMQTT_MESSAGE_RECEIVED object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didReceiveDeviceStatesMessageNotification:) name:NOTIF_DEVICE_STATES_RECEIVED object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didReceiveDeviceOnOffStateNotification:) name:NOTIF_DEVICE_ON_OFF_STATE_RECEIVED object:nil];
}
- (void)removeNotificationObserver
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIF_ESSMQTT_MESSAGE_RECEIVED object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIF_DEVICE_STATES_RECEIVED object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIF_DEVICE_ON_OFF_STATE_RECEIVED object:nil];
}
I am using NSNotification to refresh states of my buttons and images within this UITableViewCell.
The problem I am facing is, every time an NSNotication is received, the awakeFromNib is called. This will cause the states of my buttons and images to refresh back to its initial states. The strange thing is, I never saw removeFromSuperview getting called before that.
So my questions are:
Why is awakeFromNib getting called when NSNotification is received?
I am just wondering, is adding observer under awakeFromNib the correct thing to do when you want your UITableViewCells to observe NSNotifications? (Well, I've been doing this all the time.)
Because your cell was refreshed content but did not be remove from superview
You had to call removeNotificationObserver when content of cell was refreshed successfully.
I suggest you using protocol instead of notification.
Hope help.
I added a NSNotificationCenter to a UIView, when I first go to the page, the NSNotificationCenter work fine.
However, when I left that page and back to that page again, it will give out error
'NSInvalidArgumentException', reason: '-[UITextMagnifierTimeWeightedPoint updateProfile:]: unrecognized selector sent to instance.
Here are the code.
UIView1 :
- (void)changeUIView {
UIView2 *view = [[UIView2 alloc] init];
// show UIView2
}
UIView2 :
- (id)init {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateProfile:) name:#"updateProfile" object:nil];
return self;
}
-(void)updateProfile:(NSNotification *)notification {
// do something
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:#"updateProfile"];
}
- (void)buttonClick {
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateProfile" object:nil userInfo:nil];
}
You need to remove self as the observer not the selector you are using to handle the notification
[[NSNotificationCenter defaultCenter] removeObserver:self];
Or if you want to be specific you can use
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"updateProfile" object:nil];
Always
Add NSNotificationCenter in viewDidAppear
And
Remove NSNotificationCenter in viewDidDisAppear
My code:
-(void)viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleKeyboard:) name:UIKeyboardWillChangeFrameNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)handleKeyboard:(NSNotification*)notification {
NSLog(#"triggered");
}
See:
The disappearing handler is triggered once as normal, but 3 times when appears. Is this a iOS bug?
Possibly not helpful for your problem but you need to be calling [super viewWill… for your overrides.
-(void)viewWillAppear:(BOOL)animated
-(void)viewWillDisappear:(BOOL)animated
From the docs.
If you override this method, you must call super at some point in
your implementation.
Below is what I have.
MainViewController.m
- (IBAction)sideMenuAction:(id)sender {
NSLog(#"login==sideMenuAction");
[[NSNotificationCenter defaultCenter] postNotificationName:#"ShowMySideMenuNotification" object:self];
}
NotificationListener.m
-(void)viewDidLoad {
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"ShowMySideMenuNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(adjustShowMenu) name:#"ShowMySideMenuNotification" object:nil];
}
-(void) adjustShowMenu {
NSLog(#"notification adjustShowMenu=");
}
Now when I click side menu button in MainViewController, what I was expecting is call adjustShowMenu from NotificationListener once, however it is called twice.
Below is the NSLog for the same.
2015-01-20 12:27:30.798 abc[699:169314] login==sideMenuAction
2015-01-20 12:27:30.798 abc[699:169314] notification adjustShowMenu=
2015-01-20 12:27:30.799 abc[699:169314] notification adjustShowMenu=
What I was expecting is
2015-01-20 12:27:30.798 abc[699:169314] login==sideMenuAction
2015-01-20 12:27:30.798 abc[699:169314] notification adjustShowMenu=
Any idea what is going wrong?
Note: I also tried in viewDidAppear instead of viewDidLoad, but its giving same result.
When I searched online, many answers asked to removeObserver. I did same, but still twice notification is getting called.
As per answer here, I make changes as below and its working fine now.
-(void) viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(adjustShowMenu) name:#"ShowMySideMenuNotification" object:nil];
}
-(void) viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"ShowMySideMenuNotification" object:nil];
}
I am using NSNotifiationCenter, like a 1000 other times, and post a notification, but my observers are not hearing it? What gives?
=== THIS IS IN MY TABLEVIEW ===
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleSuccessSocket)
name:kNotificationServiceStartSuccessful
object:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleFailedSocketConnection)
name:kNotificationSocketFailedToConnect
object:self];
}
=== THIS IS IN MY SOCKETMANAGER (socket manager is a singleton if that matters) ===
-(void)willStartService {
....
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationServiceStartSuccessful object:nil];
....
}
I have debugged and viewDidLoad is being called in my view. Yes, my willStartService is being called.
You are registering the TableView only for notifications sent by itself. It should be..
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleSuccessSocket)
name:kNotificationServiceStartSuccessful
object:nil];
Try setting object:nil in your -addObserver:selector:name:object method calls. What you're doing is telling Notification Center to ONLY listen for notifications that come from the table view instance.
If you don't want to pass nil you'll have to pass an instance of your socket manager.
Check the Docs:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNotificationCenter/addObserver:selector:name:object: