How to set title Edit and Done for Button from UIBarButtonItem? - objective-c

I have a problem,Top button does not change own name but it works
- (IBAction)switchEdit:(UIBarButtonItem *)sender {
sender.possibleTitles = [NSSet setWithObjects:#"Edit", #"Done", nil];
if (sender.style == UIBarButtonSystemItemEdit){
sender.style = UIBarButtonSystemItemDone;
[self.navigationItem.rightBarButtonItem setTitle:#"Done"];
self.tableView.editing = NO;
}else{
sender.style = UIBarButtonSystemItemEdit;
[self.navigationItem.rightBarButtonItem setTitle:#"Edit"];
self.tableView.editing = YES;
}
}

Consider using UIViewController's editButtonItem property, since it seems to do automatically what you need:
Returns a bar button item that toggles its title and associated state
between Edit and Done.
If you want to keep your approach, you can declare these two buttons as properties and set them up in viewDidLoad for example, like that:
#interface ViewController ()
#property (nonatomic, strong) UIBarButtonItem *editBarButtonItem;
#property (nonatomic, strong) UIBarButtonItem *doneBarButtonItem;
#end
and then
- (void)viewDidLoad
{
[super viewDidLoad];
self.editBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editSelectorName)];
self.doneBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneSelectorName)];
}
and then in your code just do:
self.navigationItem.rightBarButtonItem = self.editBarButtonItem
or
self.navigationItem.rightBarButtonItem = self.doneBarButtonItem

Related

How to make sliding menu with tabs in ios

I am using ZUUIRevealController Library.
Appdelegate.h file
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
UITabBarController *tabBarController=[[UITabBarController alloc]init];
FrontViewController *frontViewController = [[FrontViewController alloc] init];
RearViewController *rearViewController = [[RearViewController alloc] init];
MapViewController *frontViewController2 = [[MapViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
UINavigationController *navigationController2 = [[UINavigationController alloc] initWithRootViewController:frontViewController2];
RevealController *revealController = [[RevealController alloc] initWithFrontViewController:navigationController rearViewController:rearViewController];
RevealController *revealController2 = [[RevealController alloc] initWithFrontViewController:navigationController2 rearViewController:rearViewController];
[revealController.tabBarItem setTitle:#"Home"];
[revealController2.tabBarItem setTitle:#"Absent note"];
revealController.tabBarItem.image=[[UIImage imageNamed:#"home_icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
revealController2.tabBarItem.image=[[UIImage imageNamed:#"absent_note_icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[tabBarController setViewControllers:[NSArray arrayWithObjects:revealController,revealController2,nil]];
[self.window setRootViewController:tabBarController];
[self.window makeKeyAndVisible];
return YES;
}
FrontViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = NSLocalizedString(#"Front View", #"FrontView");
if ([self.navigationController.parentViewController respondsToSelector:#selector(revealGesture:)] && [self.navigationController.parentViewController respondsToSelector:#selector(revealToggle:)])
{
UIPanGestureRecognizer *navigationBarPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self.navigationController.parentViewController action:#selector(revealGesture:)];
[self.navigationController.navigationBar addGestureRecognizer:navigationBarPanGestureRecognizer];
[self.view addGestureRecognizer:navigationBarPanGestureRecognizer];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Slide", #"Slide") style:UIBarButtonItemStylePlain target:self.navigationController.parentViewController action:#selector(revealToggle:)];
}
}
RearViewController is a Table ViewController
MapViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = NSLocalizedString(#"Map View", #"MapView");
if ([self.navigationController.parentViewController respondsToSelector:#selector(revealGesture:)] && [self.navigationController.parentViewController respondsToSelector:#selector(revealToggle:)])
{
UIPanGestureRecognizer *navigationBarPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self.navigationController.parentViewController action:#selector(revealGesture:)];
[self.navigationController.navigationBar addGestureRecognizer:navigationBarPanGestureRecognizer];
[self.view addGestureRecognizer:navigationBarPanGestureRecognizer];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Slide", #"Slide") style:UIBarButtonItemStylePlain target:self.navigationController.parentViewController action:#selector(revealToggle:)];
}
}
Tabs working Properly, but the sliding menu not working properly.
First I am click the Home tab and Slide menu to view the slide Viewcontroller.Next I clicked the Second tab and sliding menu to view the slide Viewcontroller. Again I've clicked the Home tab and sliding menu to view the Slide Viewcontroller. It cannot displayed only display a black screen.
I found the solution for that problem.
in Appdelegate file i have written the swreavealtoggle call for navigation.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
HomeViewController *frontViewController = [[HomeViewController alloc] init];
SlideViewController *rearViewController = [[SlideViewController alloc] init];
UINavigationController *frontNavigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
UINavigationController *rearNavigationController = [[UINavigationController alloc] initWithRootViewController:rearViewController];
SWRevealViewController *revealController = [[SWRevealViewController alloc] initWithRearViewController:rearNavigationController frontViewController:frontNavigationController];
revealController.delegate = self;
self.viewController = revealController;
[self.window setRootViewController:self.viewController];
[self customizeInterface];
[self.window makeKeyAndVisible];
return YES;}
Then create a viewController to add a Tabbar item components.
Myviewcontroller name is HomeViewController.h
after i include the tab item button click action
#import <UIKit/UIKit.h>
#interface HomeViewController : UIViewController<UITabBarDelegate>{
UITabBar *mainTabBar;
UIViewController *tab1vc; // view controller of first tab
UIViewController *tab2vc; // view controller of second tab
UIViewController *tab3vc; // view controller of first tab
UIViewController *tab4vc; // view controller of second tab
}
#property (nonatomic, retain) IBOutlet UITabBar *mainTabBar;
#property (nonatomic, retain) UIViewController *tab1vc;
#property (nonatomic, retain) UIViewController *tab2vc;
#property (nonatomic, retain) UIViewController *tab3vc;
#property (nonatomic, retain) UIViewController *tab4vc;
#end
HomeViewController.m
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
// item is the selected tab bar item
switch (item.tag) {
case 1:
if (tab1vc == nil) {
self.tab1vc =[[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
}
[self.view insertSubview:tab1vc.view belowSubview:mainTabBar];
self.title = #"Home";
label.text = self.title;
//[tab1vc release];
NSLog(#"1st");
break;
case 2:
if (tab2vc == nil) {
self.tab2vc =[[Tab2 alloc] initWithNibName:#"Tab2" bundle:nil];
}
[self.view insertSubview:tab2vc.view belowSubview:mainTabBar];
//[tab2vc release];
self.title = #"Tab2";
label.text = self.title;
NSLog(#"2st");
break;
case 3:
if (tab3vc == nil) {
self.tab3vc =[[Tab3 alloc] initWithNibName:#"Tab3" bundle:nil];
}
[self.view insertSubview:tab3vc.view belowSubview:mainTabBar];
//[tab2vc release];
self.title = #"Tab3";
label.text = self.title;
NSLog(#"3rd");
break;
case 4:
if (tab4vc == nil) {
self.tab4vc =[[Tab4 alloc] initWithNibName:#"Tab4" bundle:nil];
}
[self.view insertSubview:tab4vc.view belowSubview:mainTabBar];
//[tab2vc release];
self.title = #"Tab4";
label.text = self.title;
NSLog(#"4th");
break;
default:
break;
}
}
Now its working good

Mirror text from UITextField on inputAccessoryView - UIToolBar to text on UITextField on navigationController.toolbar

In my app I have a UITextField on the navigationController toolbar.
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic,strong) NSArray *toolBarButtonItems;
#property (nonatomic,strong) UITextField *textField;
#property (nonatomic,strong) UITextField *textField2;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 60, 40)];
self.textField.delegate = self;
self.textField.borderStyle = UITextBorderStyleRoundedRect;
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.textField];
self.toolBarButtonItems = #[flexibleSpace,barButtonItem,flexibleSpace];
self.toolbarItems = self.toolBarButtonItems;
self.navigationController.toolbar.barTintColor = [UIColor blueColor];
[self.navigationController setToolbarHidden:NO animated:NO];
}
When the textField is clicked the keyboard opens up and I create a new inputAccessoryView toolbar with another textField.
-(UIToolbar *)addToolBar{
UIToolbar *toolbar = [[UIToolbar alloc]initWithFrame:self.navigationController.toolbar.frame];
toolbar.barTintColor = [UIColor darkGrayColor];
self.textField2 = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 60, 40)];
self.textField2.delegate = self;
self.textField2.borderStyle = UITextBorderStyleRoundedRect;
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.textField2];
[toolbar setItems:#[flexibleSpace,barButtonItem,flexibleSpace]];
return toolbar;
}
The idea is to change the firstResponder to the textField on the inputAccessoryView so this way I can see what I'm editing. The reason I am doing this is cause I can't scroll the Navigation toolbar up past the keyboard and I want to see the text that I am editing.
-(void)textFieldDidBeginEditing:(UITextField *)textField{
textField.inputAccessoryView = [self addToolBar];
if(self.textField2.isFirstResponder != NO){
[self.textField2 becomeFirstResponder];
}
}
It doesn't seem to be working when I click on the textField in the navigationController toolbar. The new inputAccessoryView toolbar shows up over the keyboard but I can't edit the field because the responder doesn't seem to be changing. The return key doesn't work either. I have to hit it twice in order to close the keyboard and when I do the text doesn't match up between the two text fields.
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
self.textField.text = self.textField2.text;
return YES;
}
I got it to work like this:
#import "KJMViewController.h"
#interface KJMViewController ()
#property (strong, nonatomic) UITextField *textField1;
#property (strong, nonatomic) UITextField *textField2;
#end
#implementation KJMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.textField1 = [[UITextField alloc]initWithFrame:CGRectMake(30, 7, 260, 30)];
self.textField1.borderStyle = UITextBorderStyleRoundedRect;
self.textField1.delegate = self;
UIToolbar *navToolbar = self.navigationController.toolbar;
[navToolbar addSubview:self.textField1];
UIToolbar *toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
self.textField2 = [[UITextField alloc]initWithFrame:CGRectMake(30, 7, 260, 30)];
self.textField2.borderStyle = UITextBorderStyleRoundedRect;
self.textField2.delegate = self;
[toolbar addSubview:self.textField2];
self.textField1.inputAccessoryView = toolbar;
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(firstRes:) name:UIKeyboardDidShowNotification object:nil];
}
- (void)firstRes:(id)sender
{
[self.textField2 becomeFirstResponder];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.textField2) {
self.textField1.text = self.textField2.text;
}
[textField resignFirstResponder];
[self.textField1 resignFirstResponder];
return YES;
}
- (void)viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter]removeObserver:self forKeyPath:UIKeyboardDidShowNotification];
[super viewDidDisappear:animated];
}
#end
Here's what's happening in viewDidLoad:
Initialise toolbar and textField2
Set the inputAccessory for textField1 (the one hidden by the keyboard) here so it's ready to become firstResponder
Then in the viewDidAppear method:
Sign up for a notification that's sent when the keyboard is shown. You'll then write some code in the "firstRes" method to make textField2 the firstResponder. You need to make it the firstResponder using this notification because you know that it's in the view hierarchy by this time, which means it's able to become firstResponder. Calling it in the -(void)textFieldDidBeginEditing:(UITextField *)textField seems to fire it before textField2 comes on screen, meaning that it can't become firstResponder. We sign up for it in the viewDidAppear method because we only want to get the notification if we're on screen.
After textField2 resignsFirstResponder, textField1 becomes first responder again, so you have to call resignFirstResponder twice in the textFieldShouldReturn method.
Also, if we leave the screen, we need to remove ourself as an observer of the keyboard notification in the viewDidDisappear method.
Here's a link to the project I made in Xcode so you can see how it works:
https://github.com/kylejm/UIToolBar-UITextView

How can I reuse a UIView and methods - DRY code in iOS

I have 2 methods that add the Previous, Next & Done toolbar above the iOS Keyboard and handle these actions. I'm looking for a way to code these methods once and reuse it across multiple UITableViewControllers. (DRY Code)
I find myself copy and pasting these methods into each UITableViewController. If I make a small change, I have to copy and pastes that change everywhere. The code below is just an example, I seem to be repeating myself a lot in my code.
Here's an example of the code I'd like to reuse:
- (void) createInputAccessoryView
{
_inputAccView = [[UIView alloc] initWithFrame:CGRectMake(10,0,310,42)];
UIToolbar *keyboardToolbar = [[UIToolbar alloc] init];
keyboardToolbar.barStyle = UIBarStyleBlackTranslucent;
[keyboardToolbar sizeToFit];
_segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Previous", #"Next", nil]];
[_segmentedControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[_segmentedControl addTarget:self action:#selector(nextPrevious:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *nextPrevButton = [[UIBarButtonItem alloc] initWithCustomView:_segmentedControl];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(resignKeyboard)];
NSArray *barItems = [NSArray arrayWithObjects:nextPrevButton, flexSpace, doneBtn, nil];
[keyboardToolbar setItems:barItems];
[_inputAccView addSubview:keyboardToolbar];
}
- (void) nextPrevious:(id) sender
{
switch(_activeTxtField.tag) {
case 1:
//Recipe Name
if (_segmentedControl.selectedSegmentIndex == 1){
[_descriptionTextField becomeFirstResponder];
_activeTxtField = _descriptionTextField;
}
break;
case 2:
//Recipe Description
if (_segmentedControl.selectedSegmentIndex == 0){
[_nameTextField becomeFirstResponder];
_activeTxtField = _nameTextField;
}
default:
break;
}
}
Create a custom UIView that defines the common input accessory view. Should include a definition of a delegate to allow the class using the accessory view to handle, for example, previous/next button taps as appropriate. Here's a header file example for a keyboard accessory view:
#import <UIKit/UIKit.h>
#class KeyboardAccessoryView;
#protocol KeyboardAccessoryViewDelegate <NSObject>
-(void)accessoryNext:(id)sender;
-(void)accessoryPrevious:(id)sender;
#end
#interface InputAccessoryView : UIView
#property (nonatomic, weak) id<KeyboardAccessoryViewDelegate> delegate;
#property (nonatomic, setter = enablePrevious:) BOOL previousEnabled;
#property (nonatomic, setter = enableNext:) BOOL nextEnabled;
-(id)initPreviousNextAccessory;
#end
Edit - showing details of use in a UIViewController.
The .h file:
#import <UIKit/UIKit.h>
#import "KeyboardAccessoryView.h"
#interface MyViewController : UIViewController <KeyboardAccessoryViewDelegate>
//...
#end
The .m file:
#import "MyViewController.h"
#interface MyViewController () {
KeyboardAccessoryView *inputAccessoryView;
}
#end
#implementation MyViewController
//...
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputAccessoryView = [[KeyboardAccessoryView alloc] initPreviousNextAccessory];
inputAccessoryView.delegate = self;
//...
}
-(void)accessoryNext:(id)sender{
// handle Next
}
-(void)accessoryPrevious:(id)sender{
// handle Previous
}
//...
#end

presentPopoverFromBarButtonItem

I am trying to display my popover menu whenever the user clicks on a button.
I have two methods, the first creates the button
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *btnMenu = [[UIBarButtonItem alloc]initWithTitle:#"Forms List" style:UIBarButtonItemStyleBordered target:self action:#selector(showPopover:)];
self.navigationItem.leftBarButtonItem = btnMenu;
}
And the second is called by the first, to display the popover
-(IBAction)showPopover:(id)sender{
NSLog(#"called with %#", sender);
self.popoverController = popoverController;
popoverController.delegate = self;
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Presently, when I click the button nothing happens. I think the problem lies in the second method, mainly the presentPopoverFromBarButtonItem line.
Any help would be appreciated, I don't really understand how that method call works.
Thanks.
EDIT 1:
Here is the code where I (think) initialize the popoverController
#interface DetailViewController ()
#property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
#end
#implementation DetailViewController
#synthesize toolbar, popoverController, detailItem, detailDescriptionLabel;
Have you initialized your UIPopoverController?
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:VCTHATGOESINSIDE];
If all else fails, try presenting it from rect and specify a CGRect. Hope this helps!
edit: initWith*Content*ViewController

Replace UIBarButtonItem with UIActivityIndicatorView

I want to replace my UIBarButtonItem (used for refresh) with a UIActivityIndicatorView and, when the refresh is finished, I want to turn back to the refresh button and remove the UIActivityIndicatorView.
Just create two different UIBarButtonItems
One for the activity indicator and another for a normal UIBarButtonItem.
UIActivityIndicatorView * activityView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[activityView sizeToFit];
[activityView setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin)];
UIBarButtonItem *loadingView = [[UIBarButtonItem alloc] initWithCustomView:activityView];
[self.navigationItem setRightBarButtonItem:loadingView];
[loadingView release];
[activityView release];
UIBarButtonItem * normalButton = [[UIBarButtonItem alloc] initWithTitle...];
[self.navigationItem setRightBarButtonItem:normalButton];
[normalButton release];
When you want to switch them, just reassign the rightBarButtonItem to whichever.
Updated for Swift 5.2, Xcode 11.4
class ViewController: UIViewController {
var activityIndicator = UIActivityIndicatorView()
var refreshBarButton = UIBarButtonItem()
var activityBarButton = UIBarButtonItem()
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator.sizeToFit()
activityIndicator.color = self.view.tintColor
activityBarButton = UIBarButtonItem(customView: activityIndicator)
refreshBarButton = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(refreshBarButtonPressed))
showRefreshButton()
}
func performNetworkOperation(completion: #escaping()->()) {
//simulate network operation
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
completion()
})
}
#objc func refreshBarButtonPressed() {
showActivityIndicator()
activityIndicator.startAnimating()
performNetworkOperation {
self.activityIndicator.stopAnimating()
self.showRefreshButton()
}
}
func showRefreshButton() {
self.navigationItem.setRightBarButton(refreshBarButton, animated: true)
}
func showActivityIndicator() {
self.navigationItem.setRightBarButton(activityBarButton, animated: true)
}
}
Here what works for me :
- (void) rightItemButtonWithActivityIndicator
{
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[activityIndicator startAnimating];
UIBarButtonItem *activityItem = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[activityIndicator release];
self.navigationItem.rightBarButtonItem = activityItem;
[activityItem release];
}
I was trying to do the same thing, and I thought setting self.navigationItem.rightBarButtonItem didn't work because the activity indicator wouldn't display. Turns out it was working fine, I just couldn't see it because I have a white navigation bar and the default UIActivityIndicatorView style is also white. So it was there but invisible. With the gray style I can now see it.
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
(Duh.)
I used a similar technique to update a button in a UIToolbar when a UIWebView is reloading (as it doesn't appear to be possible to show/hide individual bar button items). In this case, you need to swap out all of the items in the UIToolbar.
#property (strong, nonatomic) IBOutlet UIBarButtonItem *refreshBarButton;
#property (nonatomic, strong) UIActivityIndicatorView *activityView;
#property (nonatomic, strong) UIBarButtonItem *activityBarButton;
#property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *backBarButton;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *refreshBarButton;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *forwardBarButton;
#pragma mark - UIWebViewDelegate
-(void)webViewDidFinishLoad:(UIWebView *)webView{
[self updateButtons];
}
-(void)webViewDidStartLoad:(UIWebView *)webView{
[self updateButtons];
}
-(void)updateButtons{
/*
It's not possible to show/hide bar button items so we need to do swap out the toolbar items in order to show the progress view
*/
//Initialise the activity view
if (self.activityBarButton == nil){
self.activityView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
self.activityBarButton = [[UIBarButtonItem alloc] initWithCustomView:self.activityView];
self.activityBarButton.enabled = NO;
}
NSMutableArray *toolbarItems = [[NSMutableArray alloc] initWithArray:self.toolbar.items];
if ([self.webview isLoading]){
//Replace refresh button with loading spinner
[toolbarItems replaceObjectAtIndex:[toolbarItems indexOfObject:self.refreshBarButton]
withObject:self.activityBarButton];
//Animate the loading spinner
[self.activityView startAnimating];
}
else{
//Replace loading spinner with refresh button
[toolbarItems replaceObjectAtIndex:[toolbarItems indexOfObject:self.activityBarButton]
withObject:self.refreshBarButton];
[self.activityView stopAnimating];
}
//Set the toolbar items
[self.toolbar setItems:toolbarItems];
//Update other buttons
self.backBarButton.enabled = [self.webview canGoBack];
self.forwardBarButton.enabled = [self.webview canGoForward];
}