iOS: Call actionsheet from tabbar - ios

I've looked at all other answers for this topic on Stackoverflow but don't get really further. I've set up my Tabbar controller in Storyboard. I've defined the icons for the tabbar items also in Storyboard, the titles however I've set via code in their respective view controllers since my app offers multi-language support.
Now I want one single tabbar button which doesn't segue to another view but just calls an actionsheet. No matter on which other tabbar I am. So my questions are:
Where do I add this tab bar button? Because all other buttons I can only define after creating the segue to the new view controller
Where do I place the code for the action sheet?!

I'm not very clued up on the tabbar, however i would do the following:
Assuming you are using a TabBarController View or a Central View With a TabBar in it.
In the -viewDidLoad
NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:self.tabBarController.viewControllers];
UIViewController *sheet= [[UIViewContoller alloc] init];
sheet.title = #"Sheet";
sheet.tabBarItem.image = [UIImage....];
[tmp addObject:sheet];
[self.tabBarController setviewControllers:tmp];
self.tabBarController.delegate = self;
Then place the following
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if([viewController.Title isEqualToString:#"Sheet"])
{
//ActionSheet create code here
retrun NO;
}
else
{
return YES;
}
}

Related

ios:Bring Child view to Front view in tabbarcontroller

I am writing an application with help screens. As per my requirement I need to show the help screens when the view appears for the first time and I am placing the code on the tabbar controller class as (void)viewDidLoad:
{
[super viewDidLoad];
XDKWalkthroughController *sc = [[XDKWalkthroughController alloc]
initWithView:self.view];
[self addChildViewController:sc];
[self.view addSubview:sc.view];
sc.delegate = self;
[sc start];
}
When I am placing this code I am getting one more tabbar item along with existing tabbar item. How to avoid that in my case?
And same thing when I placed in the first view i.e in the first tab view controller view did class. Both navigation bar and tabbar are pushing the child view back.
I have tried these two scenarios, please help me with the possible solution.

Which NavigationController Method runs on every view reload (TabBarItem)

I have a NavigationController then a TabBarController which has Four Tabs.
I wanted to display Different titles on TopBar when a Different Tab is selected.
One way was to Embed each TabBarItem View into Navigation Controller but for some reason this doesn't seems the correct way, i wanted to apply this via code.
I managed accomplish this by using this code: (Products_ViewController.m custom class)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
But the problem is now when a tab is clicked First time, it changes the title but then it doesn't. I then applied the same code on -(void)viewDidAppear{} but still the same result.
How can i manage to display navigation top bar title (or run the above code) whenever the tab bar item is clicked or the view is shown?
Thanks!
You could implement the UITabBarControllerDelegate in the Products_ViewController.m class and execute your code in the tabBarController:didSelectViewController: method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
In the viewDidLoad method you have to set the delegate to self.

How to add UIBarButtonItem to NavigationBar while using UIPageViewController

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.

How to structure ViewControllers using Storyboard for SplitView iPad app?

I'm trying to build the interface for an app that looks like this:
I want to use the Storyboard to create the views, but I'm having trouble figuring out how now. I've dropped a SplitViewController that is hooked up to 2 navigation controllers: MasterNavigationController, and DetailNavigationController (Master is the left side menu and Detail the right side).
I was starting to build all my ViewControllers in storyboard. Then build NSArrays to hold the various ViewController stacks needed for each of the Master's menu items. So when a user taps on a menu item, I'd load the corresponding ViewController stack into the DetailNavigationController using this method:
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
But now I'm thinking, I should create a separate DetailNavigationController for each of the menu items. For example:
RecentOrdersNavigationController
CustomersNavigationController
ItemsNavigationController
...
Then when a user taps a menu item, the entire DetailNavigationController changes to the appropriate one.
How should I be structuring the the interface while using storyboard?
Use a separate viewController for each detail view. You want your code to be separate since it can get confusing fast with all the different functionality for each view. From there, you can easily swap out the the detail.
Subclass UISplitViewController and set your root splitViewController to that class. Then add this method to your UISplitViewController subclass:
-(void)setDetailControllerTo:(UIViewController *)detailController withNavControllerTitle:(NSString *)title {
[detailController view]; // this line forces the viewDidLoad method to be called
if (title) {
UINavigationController *navController = [[UINavigationController alloc] init];
[navController pushViewController:detailController animated:YES];
detailController.title = title;
NSArray *viewControllers=#[self.mainController.viewControllers[0],navController];
self.mainController.viewControllers = viewControllers;
} else {
NSArray *viewControllers=#[self.mainController.viewControllers[0],detailController];
self.mainController.viewControllers = viewControllers;
}
}
To call this method do something like this from the master view controller in the tableView:didSelectRowAtIndexPath: method
FixedSplitViewController *splitController = (FixedSplitViewController*) self.splitViewController;
CurrentEventViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"CurrentEventViewController"];
// add any setup code here
[splitController setDetailControllerTo:controller withNavControllerTitle:#"Current Event"];
If you wish to keep the master view visible in portrait rotation, add this method to the SplitViewController subclass:
-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
return NO;
}
A lot of my projects require the splitviewcontroller to always show the master view so I use this subclass to keep the master view from hiding on portrait rotation.

Set UITabBarItem title programmatically?

My app is based on a tab bar architecture. In order to have an easy internationalisation mechanic, I do not write any string in XIB files. viewdidload permits to change programmaticaly the strings in the views.
When my app launches, I can see the 4 tabs. But in fact only the first one loads its view controller. The others wait for user click to be loaded.
Tabs title can be changed using [self setTitle:#"Mouhahaha"]; in viewDidLoad of loaded view controller.
If I want to keep my internationalisation mechanic available, I do not set in my XIB the name of tabbar items. But, as at start all tab' view controllers are not loaded, I have blank titles for some tabs. The right title is set only when the user click on the tab.
I am looking for a way to set this title programaticaly for each tabbaritem. Do you have hints ?
Thanks a lot.
kheraud
my preferred method of doing this programmatically together with the storyboard is to make a subclass of UITabBarController, have my tab bar controller scene in my storyboard use the new subclass (with 3 UIViewController relationships from the tab bar controller to the desired view controller in the case below), and then override viewWillAppear:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSArray* titleKeys = [NSArray arrayWithObjects:#"top places",
#"localizablekey1",
#"localizablekey2",
#"localizablekey3",
nil];
[super viewWillAppear:animated];
int count = 0; for (UIViewController* viewController in self.viewControllers)
viewController.tabBarItem.title = NSLocalizedString([titleKeys objectAtIndex:count++], nil);
}
All you need to do is make an instance of UITabBarController, then alloc any views you want in it, then set the UITabBarController views. Make sure that your TabBarController is the one that is visible. Also make sure that any viewControllers you want in your tab bar are being imported with #import.
UITabBarController *c = [self tabBarController];
SecondViewController *s = [[SecondViewController alloc] init];
[s setTitle:#"Whatever"];
c.viewControllers = [NSArray arrayWithObjects:self, s, nil];
[s release];
Put this in the viewDidLoad method of the first controller allocated.
Alternatively you could just change the way your ApplicationDelegate sets up the TabBarController, but i won't go into that.
Hope this helps

Resources