I am trying to use the NavigationController's toolbar in my app. This toolbar's toolbarItems are suppose to change depending on which view controller is presented. this is very basic.
What I am trying to do is to add custom buttons to the toolbar using the UIBarButtonItem's "initWithCustomView:" method. However, the button won't show up on the toolbar. But if I create the UIBarButtonItem using the "initWithTitle:" or "initWithBarButtonSystemItem:" method, the button show up. For example, look at the code below:
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemBookmarks target:self action:nil];
UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:#"edit" style:UIBarButtonItemStylePlain target:self action:nil];
NSArray *array = [[NSArray alloc] initWithObjects:item1, item2, nil];
[self setToolbarItems:array];
If this is done, buttons show up on the toolbar. But, if I were to do the following:
UIButton* replyBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[replyBtn setImage:[UIImage imageNamed:#"Reply_Message.png"] forState:UIControlStateNormal];
[replyBtn addTarget:self action:#selector(replyButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
replyBtn.frame = CGRectMake(10, 0, 40, 40);
UIBarButtonItem *replyButton = [[UIBarButtonItem alloc] initWithCustomView:replyBtn];
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemBookmarks target:self action:nil];
UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:#"edit" style:UIBarButtonItemStylePlain target:self action:nil];
NSArray *array = [[NSArray alloc] initWithObjects:item1, replyButton, item2, nil];
[self setToolbarItems:array];
In this code, only the item1 and item2 are displayed on the toolbar. replyButton is not shown on the toolbar. There is blank space at the place where the button is suppose to be at.
If this same code used on a regular toolbar that I create instead of NavigationController's toolbar, the button shows up. I am trying to just use one toolbar throughout the app to have the same feel that Apple's Mail application does. The reason that I need to use the "initWithCustomView:" method is because one of the icons is colored and this is the only way it shows up colored on a normal toolbar. Now, I have looked through apple documentation and there isn't any mention of why the "initWithCustomView:" method couldn't be called (or maybe I couldn't find it).
Could please somebody shine some light on this topic to help me point in the right direction. thanks in advance guys.
I can't see the difference from what you tried, but it eventually worked for me, with that code:
//////////////////////////////////////////////////////////////////////////////////////////////
/////>>>> Adding buttons for browsing in the toolbar of the popover's navigation controller///
//////////////////////////////////////////////////////////////////////////////////////////////
//>>>>Create a goBack button
goBack = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *goBackImage = [UIImage imageNamed:#"back1.png"];
[goBack setImage:goBackImage forState:UIControlStateNormal];
[goBack addTarget:self action:#selector(goBackClicked:) forControlEvents:UIControlEventTouchUpInside];
goBack.frame = CGRectMake(0,0,goBackImage.size.width,goBackImage.size.height);
//Create a Bar button to hold this button
UIBarButtonItem *goBackBarButton = [[[UIBarButtonItem alloc] initWithCustomView:goBack] autorelease];
UIBarButtonItem *flex1 = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease];
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRewind target:nil action:nil] autorelease];
NSArray *arrayOfButtons = [[[NSArray alloc] initWithObjects:goBackBarButton, flex1, addButton, nil] autorelease];
[self setToolbarItems:arrayOfButtons];
Note few differences from yours (maybe that's where the catch? I'm not sure):
1. my buttons are not allocated locally in the method, but in the class (you know, the property, synthesize, etc)
2. yours
[replyBtn setImage:[UIImage imageNamed:#"Reply_Message.png"] forState:UIControlStateNormal];
where mine looks a bit different
[goBack setImage:goBackImage forState:UIControlStateNormal];
Try these tiny changes, maybe it will work :)
I was having the same problem. It turns out that the toolbar for the UINavigationController resets it's items every time a new view gets pushed on the stack. I was trying to set the toolbar items in the applicationDidFinish function, and it was not working. It worked once I set the toolbar itms in the - (void) viewDidAppear function of the viewController that was being pushed onto the navigation stack.
So, it seems like if you want the navigation controller to keep the same toolbar items throughout the application, you have to set the toolbar items in each view that you push onto the navigation controller after the view appears.
I hope that helps!
I'd wager a guess that the item isn't showing up because its view doesn't have anything in it. Are you sure there's an image called Reply_Message.png in your project? [UIImage imageNamed:#"Reply_Message.png"] might be nil.
You can use one toolbar throughout your app without using the navigation controllers toolbar. Since your code works with a non-navigationController toolbar, this might be the easiest way to accomplish what you want. In your app delegate, try adding a toolbar to window, like this. This way it is persistent throughout the app. Make sure you consider a scheme that will let you access the toolbar to add/remove buttons, or hide/show it from different view controllers.
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/////// frame sizes ////////
// compensate for the status bar
int statusBarHeight = 20;
// toolbar
int toolbarWidth = window.frame.size.width;
int toolbarHeight = 30; // I think standard size is 30
int toolbarxOffset = 0;
int toolbaryOffset = window.frame.size.height - tHeight;
CGRect toolbarFrame = CGRectMake(toolbarxOffset,
toolbaryOffset,
toolbarWidth,
toolbarHeight);
/////// toolbar //////////////////////
self.myPersistentToolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];
[window addSubview:self.myPersistentToolbar];
}
Related
my question is simple: how can i change change title of bar button in UIImagePickerController's navigation bar?
I created the controller for UIImagePickerController (triggered by the pressure onto a button) and then tried to modify its properties:
- (IBAction)chooseFromRoll:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeSavedPhotosAlbum]){
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.navigationBar.tintColor = [UIColor colorWithRed:0.42 green:0.18 blue:0.66 alpha:1.0];
//imagePicker.navigationItem.title = #"Scegli foto profilo";
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = NO;
[imagePicker.navigationController.navigationItem.rightBarButtonItem setTitle:#"Annulla"];
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
but nothing changed, only navigation bar was correctly modified.
Here's the code for function willShowViewController:
- (void) navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
label.textAlignment = 2;
label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width-200,label.frame.size.height);
label.adjustsFontSizeToFitWidth = YES;
label.font = [UIFont fontWithName:#"Futura" size:15.0];
[label setFont:[UIFont boldSystemFontOfSize:16.0]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor whiteColor]];
[label setText:#"Scegli foto profilo"];
[navigationController.navigationBar.topItem setTitleView:label.viewForBaselineLayout];
[navigationController.navigationBar.topItem.rightBarButtonItem setTitle:#"Annulla"];
}
can you tell me where's the mistake?
thanks
Here is a code snippet for twicking the title of the navigation bar in uiimage picker.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UINavigationItem *ipcNavBarTopItem;
// add done button to right side of nav bar
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Photos"
style:UIBarButtonItemStylePlain
target:self
action:#selector(saveImages:)];
UINavigationBar *bar = navigationController.navigationBar;
[bar setHidden:NO];
ipcNavBarTopItem = bar.topItem;
ipcNavBarTopItem.title = #"Photos";
ipcNavBarTopItem.rightBarButtonItem = doneButton;
}
Hope this would help you out.
EDIT:
the answer to first question is yes you can use the ibaction or just use the method i provided above to create the button, both should work. if you are using inaction, make sure you declare you controller within it so you can make it appear and dismiss it from within the action method. the answer to the second question if you want to change the title of the view that is presented when image picker from the photo album is presented then you need to create a new subview and pop it up to allow the user to select the desired image then you can change the title the way i did it above. lengthy process, i would not recommend it. the answer to the third question, try using the following code snippet where you declare your button,
[btn.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];
where the btn is the name of your button and you can modify the font name and the size. i hope my answers can help you. good luck and let me know if you need any more help.
I've spend hours on this and can't get it to work. Hope that someone can help me.
I have a UIPageViewController which works perfectly when I add it to my default view when the application starts. This is what I do:
//Step 1
//Instantiate the UIPageViewController.
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
//Step 2:
//Assign the delegate and datasource as self.
self.pageViewController.delegate = self;
self.pageViewController.dataSource = self;
//Step 3:
//Set the initial view controllers.
ContentViewController *contentViewController = [[ContentViewController alloc] initWithNibName:#"ContentViewController" bundle:nil];
contentViewController.labelContents = [self.modelArray objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:contentViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview: self.pageViewController.view];
Now I want to use a navigation controller in my initial view which then pushes the UIPageViewController on the stack, when the user clicks on a button. This works too, but when I'm in landscape mode the UIPageViewController shows only one page (which is horizontally streched) and not two, as it should be. I need to rotate the device to portrait and then back to landscape mode to force the UIPageViewController to show both pages.
I'm adding the UIPageViewController to the navigation controller with:
[self.navController pushViewController:self.pageViewController animated:NO];
When i debug my code I see that without the navigation controller the delegate methods of the UIPageViewController are called on startup. When I push the UIPageViewController on the navigation controller they're not called until I rotate the device.
Does anyone know how to solve this? Thanks in advance for any help/tips on this.
Figured this out with help from this thread.
The key is setting the spineLocation on the pageViewController when you create it through the options dictionary:
options = [NSDictionary dictionaryWithObject: [NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid]
forKey: UIPageViewControllerOptionSpineLocationKey];
And this option should be put inside of a check to see what the current interface orientation is.
In the above mentioned thread, the interface orientation is checked by a ternary operator; I put it in an if-statement so that I can use the same opportunity to tack an extra UIViewController onto the viewControllers array.
If the interface orientation is portrait, 'options' will still be nil when the pageViewController is created, and so it'll go on to create it in portrait mode with only one viewController.
Here's my whole viewDidLoad code in BookViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
_modelController = [[ModelController alloc] init];
DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0
storyboard:self.storyboard];
NSMutableArray *viewControllers = [NSMutableArray arrayWithObjects:
startingViewController,
nil];
NSDictionary *options;
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
DataViewController *secondViewController = [self.modelController viewControllerAtIndex:1
storyboard:self.storyboard];
[viewControllers addObject:secondViewController];
options = [NSDictionary dictionaryWithObject: [NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid]
forKey: UIPageViewControllerOptionSpineLocationKey];
}
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:options];
self.pageViewController.delegate = self;
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
self.pageViewController.dataSource = self.modelController;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
// Set the page view controller's bounds
self.pageViewController.view.frame = self.view.bounds;
[self.pageViewController didMoveToParentViewController:self];
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}
I am working on an iPad application, It has the split view and i want to allow the master view to be displayed/hidden with a swipe gesture similar to the way the mail app from Apple now works. I have created the split view. Could anyone please tell me how to hide/show the master view. I also want to place a button in the detail view so if user clicks that button if master view is open it will hide it, if its already hidden by pressing the same button it will show the master view.
Help appreciated
Thanks
MasterViewController *masterViewController = [[MasterViewController alloc] init];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] init];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.viewControllers = [[NSArray alloc] initWithObjects:masterNavigationController,detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
[self.window addSubview:self.splitViewController.view];
I think https://github.com/mattgemmell/MGSplitViewController will help you.
This article could helpful to you.
http://useyourloaf.com/blog/2011/11/16/mail-app-style-split-view-controller-with-a-sliding-master-v.html
I'm using a split view for an iPad app.
In my RootViewController.m file I assign two UIBarButtonItems like this
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 300.0);
// add a save button
saveButton = [[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self action:#selector(saveAction:)] autorelease];
self.navigationItem.rightBarButtonItem = saveButton;
// add a cancel button
cancelButton = [[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancelAction:)] autorelease];
self.navigationItem.leftBarButtonItem = cancelButton;
}
These buttons show up nicely when I use UITableViewStylePlain styling for the table view. But if I use UITableViewStyleGrouped, then the buttons disappear. Here is how I set my grouped style
- (id) initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithStyle:UITableViewStyleGrouped];
return self;
}
Regardless of the presence or absence of the buttons, the size of the header remains the same.
I'm clueless as to why this happening.
all help greatly appreciated
Dhoti
I am presenting a modal navigation bar controller initialized with a root controller (which is a UITableViewController). When I, initialize the UINavigationBarController to present it modally, I am also adding a "Submit" button as a right bar button item. Everything is working fine (loading with root view and Modal presentation) However, the right button is not showing.
Posting the code below -
-(IBAction) presentAddLeaveRequestModally {
AddLeaveRequestViewController *leaveRequestViewController = [[AddLeaveRequestViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:leaveRequestViewController];
UIBarButtonItem *submitButton = [[UIBarButtonItem alloc] initWithTitle:#"Submit"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(submitLeaveRequest)];
navController.navigationItem.rightBarButtonItem = submitButton;
[self.homeTabBarController presentModalViewController:navController animated:YES];
}
Any ideas if I am missing something obvious?
Got the problem ... was adding rightBarButtonItem to navController's navigationItem ... I should be adding it to rootViewController's navigationItem in viewDidLoad.
UIBarButtonItem *submitButton = [[UIBarButtonItem alloc] initWithTitle:#"Submit"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(submitLeaveRequest)];
self.navigationItem.rightBarButtonItem = submitButton;