UIBarButtonItem clickable on left but not on right of navigation controller - ios

This is really strange behavior and I'm only experiencing it in iOS8 iPads. I have a UIBarButtonItem that needs to go on the right side of the navigation bar. Here is my code to set the button:
UIBarButtonItem *btnAttOpen = [[UIBarButtonItem alloc] init];
[btnAttOpen setAction:#selector(addAttClick:)];
[btnAttOpen setImage:[UIImage imageNamed:#"addAtt"]];
[btnAttOpen setTarget:self];
[self.navigationItem setRightBarButtonItem:btnAttOpen];
When I do this, the btnAttOpen button appears where it should but is not clickable. It simply behaves as if it were a static image. The strangest part of this is if I replace setRightBarButtonItem: with setLeftBarButtonItem: the button behaves as intended.
This doesn't make sense to me. Has anyone seen this kind of behavior? Any ideas as to why this may be occurring? Thanks!

If something doesn't want to react appropriately to touches, often the problem is that one of the parent view's frames has incorrect size, which doesn't fully cover the child's frame.
You could check them, for example, by printing out view hierarchy in gdb: po [[UIWindow keyWindow] recursiveDescription]

Related

ios 8 addSubview causes a black screen in background

This is quite a strange behaviour and I couldn't figure what was wrong out. In iOS7, this code below works as expected but in iOS 8, it has a strange behaviour.
UIView *mainPopupView = [[UIView alloc] initWithFrame:CGRectMake(10, ([UIScreen mainScreen].bounds.size.height-300)/2-50+20, 300, 380)];
mainPopupView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:mainPopupView];
In iOS7, these codes add a white mainPopupView to the present view controller, everything is working properly. But in iOS8, after mainPopupView is presented, a black screen (like an UIView with Black blackgroundColor) appears behind mainPopupView. IMO there has some change about the addSubview: method, I tried various searching on Google but no result. Anyone please explains to me why this happens and how to resolve it?
Thanks in advance.
Try setting the modalPresentationStyle of your PopupViewController instance to UIModalPresentationCustom before presenting it modally.
In case you want to know why this happens, when you present a UIViewController, after the transition animation finishes, the previous view controller is removed from the window hierarchy, since it is not being displayed. When you set the modal presentation style to custom, you are telling the system not to remove the view controller that is presenting. I don't know why it was working pre iOS8.

iOS 7: UINavigationBar out of sync with UINavigationController

I have the following code:
NSArray* stack = self.navigationController.viewControllers;
NSArray* newStack = #[stack[0], stack[2]];
[self.navigationController setViewControllers:newStack animated:NO];
stack contains 3 view controllers. The problem is that the navigation bar is not removing UINavigationItems to match, so self.navigationController.navigationBar.items.count still returns 3 after running this code. Going back gets you into a weird state where you have a back button at the top that you can press but it just disappears, not taking you back any further.
Is this a bug in iOS 7 or am I just trying to do something really stupid? What's the best way to fix or work around this?
The navigationBar has its own ‘items’ stack which is not updated until viewDidAppear hits.
Which means, if we recreate the navigation controllers’ stack in viewDidLoad using i.e. setViewControllers: when we get to viewDidAppear we will have the current item added to the bars’ ‘items’ stack and therefore the UINavController viewController stack will not be in sync with the UINavBar items stack. This appears to be an iOS 7 bug.
In iOS 6.0 the 2 different stacks do not get out of sync no matter where we set the new viewControllers stack.
So try moving your code in viewDidAppear and see if that fixes the problem. I bet it will, because for me it did.
The behavior you are describing is a corrupt navigation controller stack. This is probably because you are trying to use a navigationController improperly. I don't have much context from the code here, but I am guessing you are trying to skip back to your root view controller? I think this is probably more what you would need:
https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instm/UINavigationController/popToRootViewControllerAnimated:
you will then want to add a custom back button with something like so:
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(yourMethodToPopToRoot)];
//yourMethodToPopToRoot is a method you create that runs popToRootViewController
self.navigationItem.leftBarButtonItem = backButton;
Any questions let me know.

UIBarButtonItem not disabled until view changes

I have a UINavigationController and am using the toolbar in one of my view controllers. I have several UIBarButtonItems. At various points, I disable certain buttons in the toolbar, using things like _btnEdit.enabled = NO.
This all works well except for one time where this happens when there is no user interaction. In that case, the button appears to be enabled (isn't grayed out), but doesn't accept touches. If I cover the bar with something (an action sheet from the bottom) or change the orientation of the device, it shows correctly.
I've tried self.navigationController.toolbar setNeedsDisplay] and [self.navigationController.toolbar drawRect:self.navigationController.toolbar.bounds] but neither have an any effect.
Any ideas on how to "refresh" this view? I know UIBarButtonItems don't inherit from UIView, which I feel like may be contributing to the issue.
This is the intended behaviour. The setNeedsDisplay is a good reflex try, but you don't own the navigation bar and UIBarButtonItem doesn't inherit from UIView, so we need to think of them a little differently.
Here how you can achieve your goal :
UIBarButtonItem *bbi = self.navigationItem.rightBarButtonItem;
bbi.enabled = NO;
[self.navigationItem setRightBarButtonItem:bbi animated:YES];
NOTE : self is a UIViewController
I've just made a quick test with this and it's working.

Add image UIBarItem to UINavigationController or alternative

I have a UINavigationController with a left and a right button on an app being used as a remote control for a piece of hardware. I would like to show that the hardware is connected to the app by displaying an icon in the navigation bar to the left of the right button. From the documentation it looks as though I can only add UIBarButtonItems which make me suspect there is another, more conventional place for my 'connected LED' indicator.
So my question is can I display an icon in a UINavigationController navigation bar and if not where should I display it?
UINavigationBar is a subclass of UIView, so you can add items to it like this:
[navBar addSubview:whatever];
The navigation bar is a property of the navigation controller (i.e. you can reference it like this self.navigationController.navigationBar).
There isn't really a "conventional place" for something like this. :)
I suspect this 'connected LED' should be displayed on all views, regardless of the current view (and its UINavigationItem). If that is correct, the easiest way would probably be to NOT put that icon in the actual UINavigationBar, but place it as a separate UIView in the UINavigationBar's superview.
you should be able to just create a uiview programatically and add it as a subview of the navbar
UIImageView *connectedView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"connected-icon.png"]];
[self.navigationController.navigationBar insertSubview:connectedView atIndex:0];
[connectedView release];
if insertSubview doesn't work as you expect try addSubview:
[self.navigationController.navigationBar addSubview:connectedView];
You probably want to create the connectedView as a property though so you can (more) easily remove it when you are no longer "connected".
see this other examples of the approach
try this code
[[[yourViewController viewControllers] lastObject] navigationItem].titleView = yourImageView;
worke for me in customising navigation bar in mail controller. Hope you get some idea from here.

blank space on the view when hiding uitabbar

I know there are other posts about this issue, but they don't seem to work for me. When a particular view is pushed by my uinavigationcontroller in my app, I rotate the view to landscape mode and hide the tabbar. however, when the tabbar hides instead of displaying the view behind it displays a blank white space.
To solve this I used the following line of code in my viewDidLoad method as suggested by other posts about this issue, but it didn't solve it.
[self.view setFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
If anyone knows what's going on, please help.
Thanks,
You should set setAutoresizingMask: in your view (whether in nib or code) to UIViewAutoresizingFlexibleHeight or UIViewAutoresizingFlexibleBottomMargin (don't sure which one) that should do the trick. In case this donesn't solved your problem I guess that you hide the tabbar by using setHidden:. Try calling this instead.
VIEW_CONTROLLER_THAT_ABOUT_TO_SHOW.hidesBottomBarWhenPushed = YES
[navigationController pushViewController: VIEW_CONTROLLER_THAT_ABOUT_TO_SHOW animated: YES];
If your view is the right size then try calling [self.view setNeedsDisplay]. It should do something similar when you change the size though so I'm not sure.

Resources