Change Visuals On Another Tab - objective-c

I have a tab bar view in my Xcode app and it has two views. View 1 and View 2. When i press a button on View 1 i want a label on View 2 to say hi but i am having trouble doing this. Does anyone have any suggestions.

In the button method, you can get a reference to the tab bar controller with the view controller's tabBarController property. From that reference, you can get the view2 controller reference from the tab bar controller's viewControllers array. Once you have that reference, you need to change that view controller's tabBarItem.title property, and then finally, you need to update the tab bar controller's viewControllers array.
-(IBAction)ChangeTabTitle:(id)sender {
UIViewController *cont2 = [self.tabBarController.viewControllers objectAtIndex:1];
cont2.tabBarItem.title =#"Hi";
self.tabBarController.viewControllers = self.tabBarController.viewControllers;
}

Related

Pushing a navigation controller is not supported- performing segues

I created a new navigation controller in my storyboard (not programmatically!) and set it to be "Root View Controller" to a regular UIViewController and added a button in it which says- forward to the next view controller (this second view controller is a view controller which I want that will have a back button to link to the initial view controller).
Now, whenever I try to link the button to the next view controller- "Pushing a navigation controller is not supported".
Help me please, and thanks
EDIT:
I accidentally subclassed UINavigationController, and not UIViewController in my class.
Thank you anyway.
I've tried this and have no problems, its all done in IB with no additional code required ...
Start a new project, "Single View Application" using story boards
Select storyboard and delete the views its produced.
Drag on a new Navigation Controller (it will bring a table view with it)
Delete the table and the table view controller, so you are just left with the Navigation Controller
Drag on a normal view controller
Right Click and drag from the Navigation controller to the new View and choose "Relationship - Root View Controller"
Drag a "Bar Button Item" on to the Navbar which should be visible on the top of your ViewController, you can rename this Forward if you wish.
Now drag on another view controller which is the one your "Forward" button will push in to view.
Right Click and drag from the bar button to the 2nd View Controller, and choose "Push"
Run the project and you will get a Single view with a Navbar and your button, clicking your button will Push the other view and give you a Back Button to return to the first View Controller. I'll try and post a picture of my storyboard if it helps.
Plasma
I had the same trouble. I wanted to have a navigation controller on each storyboard, so that each could run independently, be individually debugged, and so that the look would be right with the navigation bar.
Using other approaches, I found the UINavigationController would be retained from the original storyboard -- which I didn't want -- or I'd get errors.
Using the AppDelegate in your view controller to set the rootViewController worked for me (borrowing segue naming conventions from Segue to another storyboard?):
- (void)showStartupNavigationController {
NSLog(#"-- Loading storyboard --");
//Get the storyboard from the main bundle.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Startup" bundle:nil];
//The navigation controller, not the view controller, is marked as the initial scene.
UINavigationController *theInitialViewController = [storyBoard instantiateInitialViewController];
NSLog(#"-- Loading storyboard -- Nav controller: %#", theInitialViewController);
//Remove the current navigation controller.
[self.navigationController.view removeFromSuperview];
UIWindow *window = [(AppDelegate *)[[UIApplication sharedApplication] delegate] window];
window.rootViewController = theInitialViewController;
To swap views Programatically you would need to select the segue and give it an Identifier like "PushView" then call it like this ....
[self performSegueWithIdentifier:#"PushView" sender:self];
That will programatically do the same as clicking the forward button. I've created you an example project with the code discussed above. Has an -(IBAction) with code in you can use for programatially changing the view.
PushView.zip
I also wanted to do this, present a screen (that had an embedded navigation controller) when the user pushes a button.
At my first attempt, I connected the segue from the button in the fist screen to the Navigation Controller, and the app was crashing with this error "Pushing a navigation controller is not supported".
This is the solution I found:
Select the segue from the button in the first screen to the navigation controller.
If it had an identifier, copy its name. Then delete that segue.
Then create a new segue by CTRL-clicking the button in the first view controller and dragging to the VIEW CONTROLLER YOU WANT TO PRESENT (not to the Navigation Controller that is pointing at it), and select Push in the small pop up window.
Then click the icon in the middle of the segue and paste the name you copied in the first step as an identifier for it.
IB is going to give you a warning "Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:." Don't worry, it works perfectly.
If you want to customize the string that is shown as the Back button to return, you can add this line in the viewDidLoad method OF THE VIEW CONTROLLER THAT IS BEING SHOWED AFTER THE BUTTON IS PRESSED, that is the Child view controller.
(replace "Settings" with the name you need)
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.topItem.title = #"Settings";
...
}

Tab bar controller not appearing correctly

I'm trying to connect Tab Bar Controller to existing part of my app, but when I do that it's "malfunctioning".
However when I run Tab Bar Controller part standalone as initial view controller it works properly like in the image below :
This is how app looks when it is run(correct behavior) :
However when I go to this tab bar controller from my main app this is how it looks like this:
My main app looks like this :
Scroll View contains
UIView 1
UIView 2
UIView 3
UIView x
Each view does something not related to this tab bar controller. Only one view view x tries to "visit" tab bar controller and display some data there, but it's not. Any ideas?
I have this tab bar controller identifier set to test, and I here is how I do that from my view x :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self.view addSubview:newViewController.view];
EDIT :
Entire app :
I'm creating views programatically. That's why I don't have any relationships/segues to the tab bar controller.
SOLUTION :
Change :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self.view addSubview:newViewController.view];
To :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self addChildViewController:newViewController];
[self.view addSubview:newViewController.view];
You need to set a root viewController to the navigation Controller
Just don't do this. From the Apple UITabBarController referenece
Because the UITabBarController class inherits from the UIViewController class, tab bar controllers have their own view that is accessible through the view property. When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller.
As I understand it means you must use UITabBarController only as a root view controller of the window. But you can alway use a general UIViewController and add UITabBar there.
(The view offset problem you've met is possible to be fixed, it will not follow the Apple guidelines however and not advised).

iOS - Set UIToolBarItem on UINavigationController

I drag out a toolbaritem in storyboard and set it on my nav controller, but when I run my code it's not there, is there something I'm missing?
EDIT:
Tried setting it in code as well in my viewDidLoad method:
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Map" style:UIBarButtonItemStyleBordered target:self action:#selector(viewMap)];
self.navigationItem.rightBarButtonItem = rightBarButton;
Won't work either.
Here's how it's set up in my storyboard:
UPDATE:
Just found my problem. In my controller code when I update it's contents I change the right bar button item for a spinner and never set it back to what it had before.
UINavigationController already has a toolbar built in. It has a property toolBarHidden which is set to YES by default, which is why it is not normally seen. If you are using storyboard you can easily make the built-in bottom toolbar visible by checking the checkbox "Shows Toolbar" in the inspector when the Navigation Controller is selected.
See the UINavigationController documentation here for more details.
EDIT:
Ok, it sounds like what you are trying to do is add a right button to your view controller's UINavigationItem. To do this in storyboard, drag a "Bar Button Item" from the Objects Library onto the Navigation Item in your ViewController. You can then set the title/style/etc of the bar button item. If nothing still shows up when you run your app, make sure that your ViewController is connected properly with a segue to the navigation controller.
Also make sure you are adding the Bar Button Item to your view controller's Navigation Item, NOT to the View Controller itself. Here is how the setup should look in your storyboard:
To add an item to a navigation bar, you need to add a Bar Button Item to the Navigation Item contained in the view controller. Go to your storyboard, find the right VC, and find the navigation item (it's in the hierarchy shown in the navigation controller 'scene'). Just drag a Bar Button Item into that hierarchy underneath the nav item, or directly onto the navbar in the visual builder display.
The navigation controller only looks at your VC's nav item when that VC is pushed onto the stack; hence modifying the VC's nav item in viewDidLoad has no effect.
(I've done this programmatically before but I don't have the code with me, so maybe I'll add that later...)

Back button not appearing on pushed UIViewController

I have a UITableViewController. When I click on a cell I want to push a new view. This works fine, but the new view doesn't have a back button. Why is this?
TableViewCode:
if([[NSUserDefaults standardUserDefaults] boolForKey:#"isLoggedIn"])
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
ProfileViewController* profileViewController = [[ProfileViewController alloc] initWithNibName:#"ProfileViewController" bundle:nil];
profileViewController.message = [NSDictionary dictionaryWithObjectsAndKeys:cell.textLabel.text, #"user_login", #"default", #"message_source", nil];
switch(indexPath.row) {
case kUsernameRow:
[self.navigationController pushViewController:profileViewController animated:YES];
[profileViewController release];
break;
case kAboutRow:
break;
case kTOSRow:
break;
}
}
If your table view controller is created from nib, its default title is #"" (notice: not nil, but an empty string).
Back button has a bug where it doesn't display if title of previous controller on navigation stack is an empty string, so inside your table view controller, you need to set title to either nil or some string in code, or some string in Interface Builder (can't set it to nil there afaik).
From Apple documentation:
The bar button item on the left side of the navigation bar allows for navigation back to the previous view controller on the navigation stack. The navigation controller updates the left side of the navigation bar as follows:
If the new top-level view controller has a custom left bar button item, that item is displayed. To specify a custom left bar button item, set the leftBarButtonItem property of the view controller’s navigation item.
If the top-level view controller does not have a custom left bar button item, but the navigation item of the previous view controller has a valid item in its backBarButtonItem property, the navigation bar displays that item.
If a custom bar button item is not specified by either of the view controllers, a default back button is used and its title is set to the value of the title property of the previous view controller—that is, the view controller one level down on the stack. (If there is only one view controller on the navigation stack, no back button is displayed.)
Check if your Navigation controller has navigation bar enabled. Click on Navigation bar under Navigation Controller in IB and check if 'hidden' is un-ticked. If it is ticked, the navigation bar will not be shown and so the back button would be invisible too.

Problem displaying barButtonItem for popoverController in detailView

I have a splitViewContller with detailView, which is a NavigationController and delegate for SplitView.
In this NavigationController, I store the "barButtonItem" and "popoverController" arguments, that I get from the method:
splitViewController:willHideViewController:withBarButtonItem:forPopoverController:
like this:
self.barButtonItemVsebine = barButtonItem;
self.popoverController = pc;
Then, I want to display the "barButtonItem" inside a toolbar of a view, that is loaded inside the navigation view - just setting the items of toolbar:
[items addObject:pd.detailViewController.barButtonItemVsebine];
The problem is: when there are many views in the viewControllers stack of navigationController and I call popToRootViewController the "barButtonItem" doesn't show in the toolbar of the rootViewController.
I also tried to reload all buttons in the toolbar.items array every time I pop a view controller, but sometimes the button shows up, and sometimes not. All other buttons, that I create programmatically show up correctly.