Adding an activity indicator to the nav bar - ios

I have a view controller that starts an async network request when the user taps a button, then pushes another controller after the request finishes. In that intervening time, I want the navigation bar to display an activity indicator, so the user knows it's fetching data. I have this code in the IBAction for the button:
self.activityIndicator = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhite];
// I've tried Gray, White, and WhiteLarge
[self.activityIndicator startAnimating];
self.activityIndicator.hidden = NO;
UIBarButtonItem* spinner = [[UIBarButtonItem alloc] initWithCustomView: self.activityIndicator];
self.navigationItem.rightBarButtonItem = spinner;
The indicator does not appear, but this code is getting called. I've looked at other posts on the topic, and they say to do exactly this. The UI thread does not appear blocked during the call (I can tap other buttons and navigate a different path while waiting).
Am I missing something?

I solved it.
There was a cancel button there already that was going away when the keyboard did. The code that removed the cancel button didn't care whether it was removing a button or my spinner. I moved the spinner code to a later location, and all is good.

I have had trouble displaying a UIBarButtonItem if one already existed in that place. If this is the case try:
self.navigationItem.rightBarButtonItem = nil;
self.navigationItem.rightBarButtonItem = spinner;

You can also try to set the bar button item like this (if you target at least iOS 5):
self.navigationItem.rightBarButtonItems = #[spinner];

Related

iOS: possible to superimpose barbuttonitem on other barbuttonitem and swap them

I have a screen that displays some info in a textview and I would like the user to be able to edit it.
Right now, I have an edit button on the right side of the navigation bar that I create in code as follows:
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStylePlain target:self action:#selector(gotoEdit)];
self.navigationItem.rightBarButtonItem = editButton;
For editing, I could launch a new view controller but it would be cleaner, I think, to just use the textview.editable property to make the text view editable.
However, I would then need to change the title and function of the uibarbuttonitem from edit to save.
You apparently cannot change the title of a system edit button and I'd just as soon not create a custom bar button item although this may ultimately prove necessary.
It is possible to hide bar button items by making their color clear and disabling interaction. Therefore, I had the idea of putting two in the same place and hiding and showing them accordingly.
Hence my question. Is it possible to put two in the same place?
Thanks for any ideas on this.
If you are using storyboards...you can drag and drop a UIButton to the rightBarButtonItem. Make this button a property and set the initial title to "Edit".
In the Action:
- (IBAction) editButton (id){
if(!isEditing){
// Prep for editing
[self.editButton setTitle:"Save" forState:UIControlStateNormal];
isEditing = true;
}else{
// Prep for save
[self.editButton setTitle:"Edit" forState:UIControlStateNormal];
isEditing = false;
}
}

Back button covers up a previous UIBarButton when pushViewController is called

My app is navigated by a slide out menu from the left. On top of each viewController is a left UIBarButton titled "Navigation", that when touched, opens the slide out menu without having to do the drag effect. I am implementing speech commands into my app, and if a user speaks "Go to Finances", it segues to a viewController titled FianceViewController through instantiateViewController to pushViewController.
This all works fine, the only problem is the back button associated with push segue covers up my "Navigation" button in the left slot of the UINavigationBar. Using self.navigationItem.hidesBackButton = YES; hides both the back button and my "Navigation" button. Is there anyway not make a back button appear when the push happens, but still allow my previously created "Navigation" bar button to be seen and used? Or is there another type of segue that I can do other than push if this UIBarButton dilemma cannot be solved?
Section of code that segues when spoken:
if ([title isEqualToString:#"FINANCES"])
{
FinanceViewController *fvc = [[self storyboard] instantiateViewControllerWithIdentifier:#"finance"];
[[self navigationController] pushViewController:fvc animated:YES];
}
How are you adding the navigation button?
I would try to add it after hiding the back button, something like this:
self.navigationItem.hidesBackButton = YES;
UIButton *navigationButton = [[UIButton alloc] initWithFrame:CGRectMake(15.0, 15.0, 100.0, 32.0)];
self.navigationController.navigationBar.backItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:navigationButton];
Instead of hiding my back button, I figured out I could simply write over it! Using fvc.navigationItem.leftBarButtonItem = self.navigationItem.leftBarButtonItem; before pushViewController, allows the "navigation" button to override the back button.

Add a button next to the back button

in iOS, is it possible to add a button next to the default back button (the one that is automatically created when you use the method pushViewController)
I've tried to use the methods setLeftBarButtonItems and setBackBarButtonItem but in vain - whenever I set the left bar button items, the default back button disappears.
Thanks for your help!
Just do
self.navigationItem.leftItemsSupplementBackButton = YES;
self.navigationItem.leftBarButtonItems = #[item1, item2];
I haven't tested the following code, but it should work as long as the backBarButtonItem has been initialised.
[[self navigationItem] setLeftBarButtonItems:[NSArray arrayWithObjects:[[self navigationItem] backBarButtonItem], [[UIBarButtonItem alloc] initWithTitle:#"Custom" style:UIBarButtonItemStylePlain target:self action:#selector(action:)], nil]];\
Essentially, you're setting the entire left bar button item array from scratch but providing the back button along with your own custom button.

Is it possible to show a real Popover instead of default slide-out menu when using a UISplitViewController?

I am currently working with a UISplitViewController and instead of having this default slide-out-menu, i want a real UIPopover that appears if i click the UIBarButtonItem. What do i have to do and is there an easy way of configuring this ?
You first need to overwrite the left bar button item, with the button that can be used to display the popover.
Use the following -
UIBarButtonItem *barBtn = [[UIBarButtonItem alloc] initWithTitle:#"Popover" style:UIBarButtonItemStylePlain target:self action:#selector(presentPopover:)];
self.navigationItem.hidesBackButton = NO;
self.navigationItem.leftBarButtonItem = nil;
Now you can use the target added, and then perform the associated function, as per your choice.
-(IBAction)presentPopover:(id)sender
{
// Perform your operations
}
Then just use a popover view controller instead with the same content you would have used in the splitview pane that slides out.

Add another button next to the "back" button on the left of a UINavigationBar

I've tried this for hours but I still cannot solve it.
When using UINavigationController and push a new view controller on top, I got a free "back" button on the left of the navigation bar. I want another button just next to it (to show a popover menu). I wonder what is the correct way to do that. Or I have to hide the free back button and make the same one by myself? If that's the case, I also need to pop the current view controller when pressing my own back button, right?
Thanks for your help.
As stated by steipete in the comment to the question, this is possible starting from iOS 5. You can use
self.navigationItem.leftItemsSupplementBackButton = YES;
and then you just need to add an UIBarButtonItem as leftButton to get a second button after the back button
UIBarButtonItem *secondButton = [[UIBarButtonItem alloc] initWithTitle:#"Second" style:UIBarButtonItemStylePlain target:self action:#selector(yourAction)];
self.navigationItem.leftBarButtonItem = secondButton;
SWIFT 5 this worked for me. Thanks
self.navigationItem.leftItemsSupplementBackButton = true

Resources