I have included numerous ViewControllers and as per the requirements, all the ViewControllers must contain the two same custom BarButton items(settings,help) in the right and so i created a separate class extending NSObject and included two UIButtons in it.
In all the ViewControllers, i imported this class and set barButtons like this:
NavigationBarButtonItems *nav=[[NavigationBarButtonItems alloc]init];
self.navigationItem.rightBarButtonItems = [nav BarButtonItems];
where, NavigationBarButtonItems is the class containing two custom Buttons in -(NSArray *)BarButtonItems; method.
Everything worked perfect. But Here is the problem, i created a viewController for one of the barButtons, say, 'settings' and i cant figure out how to present this ViewController(settings) when settings barButton is clicked as settings barButton is included in almost all the viewControllers.
Help me out. Thanks!
In the custom class Create the button like this.
-(void)createSettingbutton:(id)FromClass {
//Create Add category Button
UIButton *addSettingButton=[UIButton buttonWithType:UIButtonTypeCustom];
addSettingButton.frame=CGRectMake(0, 0, 30, 30);
[addSettingButton setBackgroundImage:[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]pathForResource:#"" ofType:#"png"]] forState:UIControlStateNormal];
**[addSettingButton addTarget:FromClass action:#selector(ButtonAction) forControlEvents:UIControlEventTouchUpInside];**
UIBarButtonItem *_addSettingButton=[[UIBarButtonItem alloc]initWithCustomView:addSettingButton];
[self.navigationItem setRightBarButtonItem:_addSettingButton];
[_addSettingButton release];
_addSettingButton=nil;
}
Now add the following code in the viewcontroller where you want to add the setting button.
[self createSettingbutton:self];//Second self is the parameter which is passed to 'FromClass' Variable.
Now in the same viewcontroller add the action for setting button
-(void)ButtonAction
{
[self.view addSubview:mSettingView.view];
//or
[self.navigationController pushViewController:mSettingView animated:YES]
}
Related
I am converting an app that is written in ios 2 to ios 9. I am not really familiar with ios 2 and I need some help. Back in ios 2 there were no view controllers and xib files were used. There was one xib file called the main window which would hold all the navigation items. In my case the main window xib has a navigation bar. And in code there is the following line
self.navigationItem.title = #"Back";
So I could see when i run the app on a simulator, in one of my views there is a button with titled "Back". But i cannot find a method for this button. Like there is no IBAction for it or a method. I am trying to add a selector for the navigationitem but it doesn't work. This is what I tried:
self.navigationItem.selector = #selector(backButtonClicked:)
How can I add a selector to a navigationItem so I can search that in the project or create my own selector.
You can add custom back button to your navigation bar this way
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(backButtonClicked:)];
self.navigationItem.leftBarButtonItem = btn;
-(void)backButtonClicked: (id)sender
{
[self.navigationController popViewControllerAnimated: YES]; // or popToRoot... if required.
}
Please forgive me, there are already a ton of questions on how to add a UIBarButtonItem to a NavigationBar programmatically but I just can't seem to get any of the solutions to work in my situation.
Here is the layout of a simple test app I have been working with to learn the UIPageViewController.
I have the page view controller working nicely with three unique viewControllers. I would now like to set unique rightBarButtonItems for each of the view controllers. I can easily set a common barButtonItem in the DetailViewController by simply doing this.
UIBarButtonItem *newButton = [[UIBarButtonItem alloc] initWithTitle:#"Whatever"
style:UIBarButtonItemStylePlain
target:self
action:#selector(doSomething)];
self.navigationItem.rightBarButtonItem = newButton;
Given that I need a unique button for each of the three pages in the pageViewController I am not able to set the button in the detailViewController. I have tried the code above in viewDidAppear of the three controllers but the buttons will not appear. I have also tried creating the button in the same way and then setting it like this with no luck.
DetailViewController *vc = [[DetailViewController alloc] init];
vc.navigationItem.rightBarButtonItem = newButton;
I know I'm close here, I'm just not sure how to specify I need to add a button to the NavigationBar of the NavigationController that is running the detailViewController that my contentViewControllers are embedded in. Any help would be great ESPECIALLY SNIPPETS.
As a side note I have tried a few other methods that have come up problematic.
Setting the button in viewDidLoad rather than viewDidAppear
This will not work because the viewDidLoad method is not called everytime you swipe from one page to the next. The viewDidAppear method is however so I am trying to set the button there. It is possible viewWillAppear is called everytime but I haven't checked.
Setting the button in the UIPageViewController delegate methods
This is problematic if the user flips through the pages to quickly the button will fail to change or fail to appear.
SOLUTION
It turns out I was close… Rather than creating the button in the UIPageViewController methods I simply needed to create a navigationItem property in each of my three view controllers. When the controllers are instantiated in the delegate methods I simply set the navigationItem property equal to that of the detailViewController. That way in my viewDidApper methods I could create the button. Then at viewWillDisappear I set the button to nil. You can also just create the button at viewdidLoad of the DetailViewController and change the text and action in viewDidAppear of the individual viewControllers. Here is a sample.
In the delegate methods
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
I call a helper method based on the index of the viewController. The helper method instantiates the view controllers when it is called. Once instantiated I set some properties including the navigationItem property.
-(FirstController *)controllerAtIndex:(NSUInteger)index
{
FirstController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:#"FirstPageController"];
fvc.imageFile = self.pageImages[index];
fvc.titleText = self.pageTitles[index];
fvc.pageIndex = index;
fvc.navItem = self.navigationItem;
return fvc;
}
Then in the viewDidAppear of the viewController I just do this
-(void)viewDidAppear:(BOOL)animated
{
UIBarButtonItem *newButton = [[UIBarButtonItem alloc]
initWithTitle:#"Whatever" style:UIBarButtonItemStylePlain target:self action:#selector(doSomething)];
navItem.rightBarButtonItem = newButton;
}
If you need the button to change each time you change the page you look at, it must be done in one of the delegate methods that you have tried. I suggest however, that instead of creating a new button and setting it to the navigation item, you simply change the title.
You can create the button in interface builder and link it to a property in your DetailViewController and then call setTitle:forState with UIControlStateNormal on the button every time you go to a new page.
If you need the button to do something different for each page, I would recommend checking the current page in the buttons action method rather than declaring a new one each time.
You can find the correct navigation item to set buttons/titles on by finding the page controller in one of its paged view controllers, then getting its nav item. e.g.
UIViewController *pageController = [[self.navigationController childViewControllers] lastObject];
pageController.navigationItem.title = #"My page's title";
It's really annoying that self.navigationItem doesn't work!
One of my colleagues experienced the same problem with page view controller.
As far as I understand, you wont' be able to add UIBarButtonItem to navigation bar of member view controllers in UIPageViewController. Reason being 'navigationController' is set to nil for UIPageViewController. To confirm, print value of [UIPageViewController navigationController].
However you can do one thing to overcome this issue. Please download example PhotoScroller.
And do following changes in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// kick things off by making the first page
PhotoViewController *pageZero = [PhotoViewController photoViewControllerForPageIndex:0];
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:pageZero];
if (pageZero != nil)
{
// assign the first page to the pageViewController (our rootViewController)
UIPageViewController *pageViewController = (UIPageViewController *)self.window.rootViewController;
pageViewController.dataSource = self;
[pageViewController setViewControllers:#[nav]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
}
return YES;
}
And following changes in the PhotoViewController.m
- (void)loadView
{
.....
.....
self.title =#"Frogs";
UIBarButtonItem *newButton = [[UIBarButtonItem alloc] initWithTitle:#"Something" style:UIBarButtonItemStylePlain target:self action:#selector(doSomething)];
[newButton setTintColor:[UIColor redColor]];
self.navigationItem.rightBarButtonItem = newButton;
}
To avoid crash, you have to handle UIPageViewControllerDataSource delegate methods correctly in AppDelegate.m
Though, I wouldn't advice you to do above as it breaks the whole concept of UIPageViewController.
I hope this would be helpful.
I have a UITabBarController bassed app. I'm instantiating it from the app delegate and adding a custom button in the tab bar controller. when that button is clicked, I want to present another view modally, but I cant seem to figure out how to do it. to add the button I'm basically doing this
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[self.tabBarController.view addSubview:button];
[button addTarget:self action:#selector(showModalViewController:) forControlEvents:UIControlEventTouchUpInside];
and also in the app delegate I have a method
- (void) showModalViewController {
DummyViewController *addController = [[DummyViewController alloc]
initWithNibName:#"DummyViewController" bundle:nil];
//addController.delegate = self;
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
// Create the navigation controller and present it modally.
[self.tabBarController.selectedViewController presentModalViewController:addController animated:YES];
// The navigation controller is now owned by the current view controller
}
I keep getting unrecognized seletor
Your selector looks for a method named showModalViewController: but your actual method is named showModalViewController. Change one or the other.
Either change the selector to #selector(showModalViewController) to match the existing method, or change the method to:
- (void)showModalViewController:(UIButton *)button {
Don't change both.
My storyboard is like this:
So from navigation controller , i am going to a tab controller.
My tab controller has its classed, named: MYTabBarView
In MyTabBarView.m , in its ViewDidLoad method I created the right bar button item programmatically like this:
UIBarButtonItem *homeButton = [[UIBarButtonItem alloc] initWithTitle:#"Home" style:UIBarButtonSystemItemAction target:self action:#selector(homeButtonAction)];
self.navigationItem.rightBarButtonItem=homeButton;
my question is how do I write an action for it. I mean if it was a button that was visible in the storyboard, I would "drag and dropped" it in the .h file and in the .m file I would have
the method:
Now what should I do?
- (IBAction)home:(id)sender {
....
}
Use the selector you typed when you created the button:
- (void)homeButtonAction {
// Code
}
And if you want to pass along the sender use #selector(homeButtonAction:) and the following method:
- (void)homeButtonAction:(id)sender {
// Code
}
I want to make a simple view with a navigation bar and a table view. So I created a subclass of UINavigationController and I added a UITableView in it. My is is also the UITableViewDataSource and UITableViewDelegate. Now I want to add UIBarButton in the navigation bar but it doesn't work :
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:[[Translator instance] getTranslation:#"Back"]
style:UIBarButtonItemStylePlain
target:self.parentViewController
action:#selector(dismissFiltersModal:)];
self.navigationItem.backBarButtonItem = anotherButton;
There's no error the view is displayed but not the button. How can I do to display it?
jafar,
as Apple doc suggested you should avoid to subclass UINavigationController.
This class is not intended for subclassing.
Said this, you could follow these simply steps (some advice for you):
Create your controller (say MyController) that extends UIViewController and add the table here. Set your controller as the delegate and data source for that table. If you have created by xib you need an outlet for your table view.
[P.S. you could also subclass a UITableViewController, it has a table view its own]
In viewDidLoad of MyController customize the navigation bar.
For example
UIBarButtonItem* myButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(someSelector)];
self.navigationItem.leftBarButtonItem = myButton;
You could also customize the title.
For example
self.title = #"Your custom title";
Somewhere in your code create a UINavigationController and add as a root view controller an instance of MyController.
For example:
MyController* myCtr = // alloc-init here
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:myCtr];
The backBarButtonItem should be set on the previous view controller, not the current one to be displayed. For example, if your you are on view A, navigate to B from it, inside B A's backBarButtonItem will be displayed, not B's.
If you just want to display an item on the left hand side of the navigation bar, you can use leftBarButtonItem instead, which will display a normal bar button on that controller. It will be rectangular, not an arrow like normal back buttons though.
How about you try this :
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape!
[backButton addTarget:self action:#selector(dismissFiltersModal:) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
// create button item --
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
// add to toolbar
self.navigationItem.leftBarButtonItem = backItem;