Question

I've got two viewControllers who each need a login button in the top right corner of the navigation bar.

In viewController1#viewDidLoad, I set up the rightBarButtonItem like so (abbreviated):

// set up the login button on the right
UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *loginImage = [UIImage imageNamed:@"btn_login.png"];
[loginButton setBackgroundImage:loginImage forState:UIControlStateNormal];
[loginButton setFrame:CGRectMake(0, 0, loginImage.size.width, loginImage.size.height)];
[loginButton setTag:1111111];
UIBarButtonItem *loginItem = [[UIBarButtonItem alloc] initWithCustomView:loginButton];
self.navigationItem.rightBarButtonItem = loginItem;
[loginItem release];

I tag it so that in viewWillAppear, I can use viewWithTag:1111111 to figure out if it needs to be hidden or visible, based on whether or not the user is logged in. Simple.

((UIButton *)[self.navigationController.view viewWithTag:LOGIN_BUTTON_TAG]).hidden = true; 

When viewController2 gets pushed onto the stack, I basically run the same code to set up my rightBarButtonItem, but I give it a different tag (i.e. 222222).

In viewController2#viewWillAppear, when I look for the viewWithTag:222222, it comes back as null, and so I can't hide/show it.

I noticed though that if I use the same tag as I used in viewController1 (1111111), I can get to it.

Why is this? My tags are actually set up at the top of the file as constants, so it seems inelegant to copy the random number from vc1 into vc2 just so I can get this to work. Instead, I'd like to understand why vc2's tag isn't getting applied to the rightBarButtonItem, and why vc1's tag is still preserved even though I'm in a different viewController.

Was it helpful?

Solution

The easiest most scalable solution is to avoid using viewWithTag: like the plague.

Make the UIBarButtonItem an ivar and then you have instant access to it without any ambiguities.

Replace

[loginButton setTag:1111111];

with

self.loginButton = loginButton;

Then to retrieve do this

self.loginButton;

instead of

(UIButton *)[[[self.navigationController visibleViewController] view] viewWithTag:LOGIN_BUTTON_TAG];

I know which one looks more elegant and robust to me

OTHER TIPS

If I understand correctly what you are doing, the first thing I would try is to check, before this line, in both viewcontrollers:

((UIButton *)[self.navigationController.view viewWithTag:LOGIN_BUTTON_TAG]).hidden = true; 

to put a

NSLog("View is %@", self.navigationController.view);

to check if you are sending viewWithTag to the correct view. Not sure about this, but Are you trying to access to a view, controller by an UIViewcontroller, loaded inside an UINavigationcontroller? In this case I would use:

(UIButton *)[[[self.navigationController visibleViewController] view] viewWithTag:LOGIN_BUTTON_TAG];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top