I've been recently developing an app that uses a freeform view controller. Everything was fine until I wanted to set the button title label's text considering localization.
I tried to set the text multiple ways but nothing seems to work. At first I was instantiating the view controller from storyboard using its storyboardID like so :
self.dropDown = [self.storyboard instantiateViewControllerWithIdentifier:#"dropDown"];
but then I realized that I cant set controller's titles. Or at least I didn't know where to set them. I have them all connected via storyboard as properties. I tried to set the button's title in the viewDidLoad method of the DropDown.m class, nothing. I've also tried to set the title in the controller where I am presenting the dropDown like so:
[self.dropDown.priceAscendingButton.titleLabel setText:NSLocalizedString(#"priceAscending", nil)];
[self.dropDown.priceDescendingButton.titleLabel setText:NSLocalizedString(#"priceDescending", nil)];
[self.dropDown.dateAscendingButton.titleLabel setText:NSLocalizedString(#"dateAscending", nil)];
[self.dropDown.dateDescendingButton.titleLabel setText:NSLocalizedString(#"dateDescending", nil)];
but nothing worked ..
Could you please help me ?
Use this
[self.dropDown.priceAscendingButton setTitle:NSLocalizedString(#"priceAscending", nil) forState:UIControlStateNormal];
Related
Im having some trouble with a view that I needed instantiating from a storyboard ID. In IOS simulator, the view loads with everything in place but is completely unresponsive. The date picker doesn't move and the buttons don't accept any interaction.
Ive checked the 'custom class' matches in IB and the Storyboard ID matches. The code is being executed in the PickerViewController because the UIDatePicker is being created in code and is correct and present in IOS simulator. Its just that nothing accepts any interaction. The buttons don't even go blue when touched.
I created the view in the previous view controller with:
PickerViewController *addViewController = (PickerViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"view"];
[addViewController.view setUserInteractionEnabled:TRUE];//chucked this line in to see if it helped
[addViewController setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:addViewController animated:YES completion:NULL];
I'm not sure if this is a code problem, or if I've not hooked something up in IB properly. Any ideas??!!
Check your view controllers class in assistant editor:
I want to add a subview (a segment control) like Viber app main screen.
I tried setting self.navigationItem.titleView = myCustomView, but it seems to not working
How can I achieve my goal?
If you are adding this code from a UIViewController inside a UINavigationController, this code should work. So You need to check some points:
This view controller is part of the navigation controller?
The navigation bar is part of the navigation controller?
Are you initializing myCustomView correctly? Is it non-nil when you do this?
Is this view controller in the top of the stack? As written in the docs, and you can see that according to what you see from apps in general, this titleView is only used when item is topmost on the stack.
Try to NSLog the following to check some of them:
NSLog(#"self.navigationItem exists? %d", self.navigationItem != nil);
NSLog(#"customView exists? %d", customView != nil);
I am trying to present a UIViewController inside a UIPopoverController. I've designed a view controller in Interface Builder, gave it a custom class (let's say MyAppTestViewController) and I'm trying to create a popover this way:
MyAppTestViewController *fxViewController = [MyAppTestViewController new];
self.fxPopover = [[UIPopoverController alloc] initWithContentViewController:fxViewController];
self.fxPopover.popoverContentSize = CGSizeMake(1024, 120);
[self.fxPopover presentPopoverFromBarButtonItem:_fxButton permittedArrowDirections:UIPopoverArrowDirectionDown animated:NO];
When I press the button, a popover is displayed at the correct place with the correct size, but it is empty. I've verified that the MyAppTestViewController's viewDidAppear method is being called (by NSLog), but the Popover's inside is empty:
Am I missing something?
I see that you mentioned in a comment that you're using a storyboard. So why not use a popover segue to your MyAppTestViewController? You could wire the segue directly to the Effects button on your toolbar. (Or, alternatively, call performSegueWithIdentifier: from your presenting view controller.) You might do a quick test by just throwing a UILabel into MyAppTestViewController right on the storyboard and seeing if it displays properly.
I think the problem is here:
MyAppTestViewController *fxViewController = [MyAppTestViewController new];
Generally you would use [[MyViewControllerClass alloc] initWithNibName:nil bundle:nil] (assuming you have a xib file with a matching name). I don't believe I have ever seen a view controller initialized with new. Everything in Objective-C is alloc-init.
Apple Docs: UIViewController Class Reference
Quote:
To initialize your view controller object using a nib, you use the
initWithNibName:bundle: method to specify the nib file used by the
view controller. Then, when the view controller needs to load its
views, it automatically creates and configures the views using the
information stored in the nib file.
EDIT:
Fascinating, well okay. It looks like you are right about the use of the new keyword, here is bit of an explanation of this.
So fine, that's not the problem. Have you tried breaking on the viewDidAppear method and using the debugger to print out the view properties, check its frame, check its superview, and so on, try to understand the problem better? You may already know how to do this, but the commands would be po self.view and so on.
In any case, I also found this, although it only goes into the mechanics of popover presentation and not content view assignment, which you seem to have down.
Okay, so far I've two view controllers in my storyboard. One with "login" elements and other as "User's home" sort of thing. I am intending to do the following : When user clicks on login, there's a bit of processing and then it should show to user's home screen..
When I do it via storyboard, i mean = control drag "login" button to user's home view it works fine. But I cant use that as I've to process the login data. It also shows some animation meanwhile. So, I've to do this shift programmatically. I wrote following code in the login button's IBAction ::
HomeViewController *homeView = [[HomeViewController alloc] init];
[self presentViewController:homeView animated:YES completion:NULL] ;
Now, this takes user to the intended view. However, the elements in the homeview (say a label, navigation bar are not being shown. And thats what my worry is.
(In theory, I can build entire view programatically but i think thats not the proper way of doing this, is it ? I want to make use of storyboard functionality in full i.e. design maximum UI in storyboard and use them from the backend how you want them to work.)
How do I do it ?
Cheers.
PS : I intend to add few more view controllers so at the moment i didn't think of navigation controller. not sure, if i should use it.
Using storyboards you should be using:
UIViewController *homeView = [self.storyboard instantiateViewControllerWithIdentifier:#"someID"];
[self presentViewController:homeView animated:YES completion:NULL] ;
Then set the ID to the view controller in storyboard like so:
Additionally, if you wish to there is absolutely nothing wrong with designing your UI entirely in code. Personally I prefer it. It gives you much more flexibility than interface builder.
In addition to NSPostWhenIdle's suggestion of instantiateViewControllerWithIdentifier, you can also define a segue between the two view controllers (not between the button and the second controller, but between the two view controllers):
Then give the segue a unique identifier, and then have your IBAction method do a performSegueWithIdentifier. This way your storyboard will continue to visually represent the various relationships between your view controllers.
I have a TabBarController set as main controller tab, where names were defined using interface builder. Now I would like to change its names programmatically.
How could it be done?
Updated to XCode 8
Since my original answer, a lot has happened: Swift 3, Storyboards, etc. Title is usually the one that all views share, and can be set in the attributes inspector
Also, for more control, you can always drag the UITabBarItem, and UINavigationItem elements from the designer view. You must drag them to the view that's gonna be displayed in the tab bar/navigation controller. Basically they store the info as "I wanna be displayed in tab bar like this".
Hello Scene is getting a TabBarItem added to it, so it can be configured.
These two elements behave exactly as accessing the view controller's .tabBarItem and .navigationItem properties via code. These properties always exist in code if they are child of the corresponding object (nav has navItem, and tab has tabItem), you don't need to add them in storyboard/xib to have them.
This last thing is kinda confusing, since in the storyboard/xib it appears you're adding them to the view controller, but in truth you're just saying "the nib will configure these properties too".
Original Answer
The name that appears on the tab bar comes from the UIViewController's title property,
self.title = #"Name me!";
You can change the title at any point, and it should update the text appearing on the tab bar item. But be wary, do this as soon as possible, ideally, in the init method in use (or initWithNibName:bundle:, or initWithCoder:).
The key here, is that the init methods are called as soon as the tab bar appears on screen, as it initialises all of its view controller. If you were to do it on viewDidLoad, that would only get called if you actually select the tab, then other family of calls, same goes for awakeFromNib, viewWillAppear:, viewDidAppear:, etc.
The idea of having a title on the UIViewController, is to keep things consistent. If you show that viewController on a UINavigationController, the navigation bar on top should use the title property, as it does when using back. The UITabBarController also respects the same title property and changes accordingly.
In terms of reusability, you should be setting the title only from the inside of the UIViewController subclass.
The way of the Nib
Using nibs or storyboards? If you have a UIViewController, you can give it the name straight up in the attributes inspector (or ⌥⌘4)
Unfortunately, if the File Owner is the UIViewController subclass, then you won't be able to access it this way, simply because, XCode registers the File Owner as an "External Object", and doesn't show a configuration panel for it. :(
Multiple titles, same view controller
But sometimes, you just want to have them named differently
// Modify the display title on the tab bar
self.tabBarItem.title = #"World";
// Modify the display title on the navigation bar
self.navigationItem.title = #"Hello World";
Screwing with the neighbours
Each UIViewController should handle his own name, what if you want to force it from the outside (and thus, completely violating the original thing I said about reusability)?
// Rename the other guy's .title property
[[self.tabBarController.viewControllers objectAtIndex:<#Index#>] setTitle:#"Hello World"];
// Or do as before, and rename the other guy's tab bar
[(UITabBarItem*)[self.tabBarController.tabBar.items objectAtIndex:<#index#>] setTitle:#"Hello World"];
You could also probably do it with the navigation item, but that would require more gymnastics than I'm comfortable with.
However it is possible to do it in code, it is better to set this directly in Storyboard. How?
Just tap the appropriate tab bar item inside controller (NOT INSIDE TABBAR CONTROLLER).
Then switch to attribute inspector on the Utilities panel.
Now you are able to change everything:-)
Swift 4+
tabBarController?.tabBar.items![1].title = "xx"
In your viewController.m
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Here you are setting title
self.title = NSLocalizedString(#"Title", #"Title");
}
return self;
}
This is how you can change the name and the image of the icon of a tab bar:
self.tabBarItem = [[[UITabBarItem alloc] initWithTitle:#"Main Tab" image:[UIImage imageNamed:#"maintab.png"]] autorelease];
You probably want to do this in UITabBarController::viewDidLoad in which case you need to set the view controller's title because the tab bar items are currently 0 at that point.
So use
[[self.viewControllers objectAtIndex:0] setTitle: #"Buga"];
[[self.viewControllers objectAtIndex:1] setTitle: #"Nuga"];
I'm using Xcode Version 8.2.1 (8C1002) and this works for me: