I am connecting between two classes with NSNotificationCenter. My problem is that although I press a button once (and this button only works once), I inadvertently increase the number of notifications from only one call to NSNotificationCenter.
Here is the best explanation for the code problem:
My two classes are the mainView class and the Menu class.
When viewing a view in the mainView class , it starts the view created and managed by the Menu class. This code is called when mainView is initialized:
menu=[[MyMenu alloc] init]; UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapped:)]; [tap setNumberOfTapsRequired:1]; [container addGestureRecognizer:tap]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChangeItem:) name:@"ItemChange" object:nil];
This gesture recognizer disables this method, also in the mainView class:
- (void) onTapped: (UIGestureRecognizer*) recognizer { NSLog(@"tap"); [menu displayMenu]; }
This is how the Menu class is initialized:
- (MyMenu*) init { self=[super init]; UICollectionViewFlowLayout * layout=[[UICollectionViewFlowLayout alloc] init]; menuView=[[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 200, 200) collectionViewLayout:layout]; [menuView setDataSource:self]; [menuView setDelegate:self]; [menuView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"]; [menuView setAutoresizesSubviews:YES]; [menuView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth]; [menuView setBackgroundColor:[UIColor clearColor]]; [menuView setIndicatorStyle:UIScrollViewIndicatorStyleWhite]; return self; }
And this is the displayMenu method inside the Menu class:
- (void) displayMenu { [viewForMenu addSubview:menuView]; }
The Menu class also has a clearMenu method:
- (void) clearMenu { [menuView removeFromSuperview]; }
This is the code for each cell in the UICollectionView contained in the Menu class:
- (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell * cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; [cell setTag:indexPath.row]; UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onButtonTapped:)]; [tap setNumberOfTapsRequired:1]; [cell addGestureRecognizer:tap]; NSLog(@"button tapped : %d",indexPath.row); return cell; }
This calls the onButtonTapped: method, also in my Menu class:
- (void) onButtonTapped:(UIGestureRecognizer*) recognizer { NSInteger buttonTapped=[[recognizer view] tag]; [[NSNotificationCenter defaultCenter] postNotificationName:@"ItemChange" object:nil userInfo:@{@"selected":@(buttonTapped)}]; [self clearMenu]; }
This notification is picked up by my mainView class with this code:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChangeItem:) name:@"ItemChange" object:nil];
This calls the onChangeItem: method inside the mainView class:
- (void) onChangeItem: (NSNotification*) notification { NSLog(@"change item to %d",[[[notification userInfo] objectForKey:@"clock"] intValue]); }
So the code.
OK, here is the problem: the first time I display the menu, I get this in my log:
...[43023:11f03] tap ...[43023:11f03] button tapped : 1 ...[43023:11f03] change item to 1
And that’s beautiful, that’s what I expect. However, the second time I get the following:
...[43023:11f03] tap ...[43023:11f03] button tapped : 1 ...[43023:11f03] change item to 1 ...[43023:11f03] change item to 1
The third time I get the following:
...[43023:11f03] tap ...[43023:11f03] button tapped : 1 ...[43023:11f03] change item to 1 ...[43023:11f03] change item to 1 ...[43023:11f03] change item to 1 ...[43023:11f03] change item to 1
And so on. Each subsequent click on a menu item doubles the number of notifications.
To begin with, I thought that I was adding several views and, therefore, getting a few short presses of buttons and, therefore, several notification calls.
However, as you can see from my magazines, this is not so. Buttons receive only one event-event - this turns off only one notification, but the receiving class receives several notifications.
Can someone explain this to me?
Sorry for the long post!