How can I hide a UIBarButtonItem? - iphone

I have created a simple UI in IB, this consists of a UINavigationBar and a UIBarButtonItem that I dragged and dropped on the right hand side.
I am trying to set this button to be hidden a certain times but I am having some problems.
So far I have tried using:
self.NavigationItem.rightBarButton = nil;
...which didn't work for me. I have also tried creating and IBOutlet and linking it to the button however I'm having problems with this too. I think it should be pretty simple and maybe I'm over-complicating it, but at this point I'm pretty stumped!
Please can someone help me out?

UINavigationItem doesnt have a rightBarButton property. Try rightBarButtonItem instead (or [self.navigationItem setRightBarButtonItem:nil animated:NO];):
self.navigationController.navigationItem.rightBarButtonItem = nil;
// Or
self.navigationItem.rightBarButtonItem = nil;
// Or
[self.navigationItem setRightBarButtonItem:nil animated:NO];

Just reset the buttons
-(void)setItems:(NSArray *)items animated:(BOOL)animated
More info here: http://developer.apple.com/iphone/library/documentation/uikit/reference/UIToolbar_Class/Reference/Reference.html#//apple_ref/occ/instm/UIToolbar/setItems%3aanimated%3a
You can get the current items using the items property, then just remove the one you don't want to show and pass in the new NSArray.

You can also add a UIButton as the UIBarButtonItem's customView. Then set the hidden property on the customView (UIButton)

Rather than deleting the bar button item and destroying the button and it's attached storyboard segue, you can just set it to clear text when it's disabled.
[self.navigationItem.rightBarButtonItem setTitleTextAttributes:#{NSForegroundColorAttributeName:[UIColor clearColor]}
forState:UIControlStateDisabled];
Then when ever you want the bar button item hidden, you can just do:
self.navigationItem.rightBarButton.enabled = NO;
It's lame there's no hidden property but this offers the same result.

Actually, you can just create an IBOutlet reference to the desired UIBarButtonItem and when needed just do as follow:
[self.yourOutletRerence setImage: nil];

The simplest solution: Just change the BarButtonItem's identifier to custom.

Related

rightbarbutton not animating properly

I am animating to a view with it sliding from right to left. The left bar button looks like it is in the navigation but the rightbarbutton seems to animated weirdly, almost like at first its not part of the navigation bar.
I am wanting to know if there is something wrong in my code... or if there is another way of doing this?
- (void)viewWillAppear:(BOOL)animated
{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Skip" style:UIBarButtonItemStyleBordered target:nil action:nil];
[super viewWillAppear:animated];
}
Any help would be greatly appreciated.
Set rightBarButtonItem in the view controller's init... method. It only has to be done once in the view controller's lifetime.
This is just a shot in the dark, but the convention is to first call [super viewWillAppear:animated], then add your own code. Do that whenever you're constructing things (objects, views, etc).
Then when tearing things down (-dealloc, -viewWillDisappear, etc.), do the opposite. Clean up your stuff, then call the super to let it do its cleanup.
That probably isn't related and won't make a difference. But it's a good habit to get in to, and you never know. It might change the behavior here. Maybe the super needs to do do some setup before you add the bar button item.

How can I set the background image of multiple buttons in a certain view from a different view?

Basically, I cannot figure out how to change the background image. I have searched and searched and just cannot seem to find it. Anyone have any ideas? Thanks!
Update
Here is the code I use to show the View:
SettingsViewController *settingsView = [[SettingsViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:settingsView animated:YES];
If anyone needs anything else to help out I'll do my best! Thanks!
Passing a messages between different views can be done by direct call of the methods (not a good architectural solution but maybe not critical for a small projects) or with an event driven model as described in an answer above.
As for binding of a collection of objects and processing the afterward I recommend to review IBOutletCollection keyword that allows to bind multiple objects fro an InterfaceBuilder to a property with a type like NSArray.
Property declaration will look like following:
#property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *buttons;
The code to change the background for all the buttons will look like following:
UIImage *backgroundImage = [UIImage imageNamed:#"background.png"];
for(UIButton *button in buttons) {
[button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
}
You use setBackgroundImage:forState: to set the image.
Regarding the different views part, it depends on how you wrote your code. If the view with the buttons is controlled by the different view (by creating an instance and using addSubview:) then you can call it directly by using instanceName.buttonName (as long as you declare it as a property -thanks fichek).
If you don't manually add the view, instead through IB, you can have the button that controls the other button's image point to the IBAction in that class.
If neither of those options work you can always use NSNotificationCenter.

Passing object data with UIButton press

I've created a custom UIView class FormDropdown, which contains a question & button in the nib. In the class is also an NSArray property which is supposed to store the various options for the button.
So a button can be placed by doing this, in for instance a viewDidLoad method:
FormDropdown *dropdown = [FormDropdown dropdownWithQuestion:#"This is an example question" andLabel:#"Select one" andOptions:[NSArray arrayWithObjects:#"One", #"Two", #"Three", nil]];
[self.view addSubview:dropdown];
Obviously, I'd like the button to, when tapped, bring up a UIPickerView with the options showing. But I'm stuck on how to send the options to any method. I know I can attach an action to the button like so:
[dropdown.dropdownButton addTarget:self action:#selector(dropdownPressed:) forControlEvents:UIControlEventTouchUpInside];
..but I can't see how I would pass the options from the dropdown.options array to the method?
I believe that you can do this by adding an "associative reference" from the UIButton to your object data.
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html
I am looking for a way to do that as well... however, it doesn't seem possible.
My possible solution: I think I am going to create a subclass of UIButton, and add a "NSObject *tagObject" property to it.
Anyone seems something wrong about it? (I am using ARC, and I am wondering if that would cause objects to remain in memory - I do not think so).

add searchbar in UItoolbar

i want to know is this possible to add a searchbar in UItoolbar
I just had a quick look and while interface builder will let you do it, when you try to save a warning pops up a warning saying the following "UISearchBars are not supported in UIBarButtonItems in non-iPad documents". That being said, it might be possible to make your own view that looks and works like a UIToolbar that does allow a UISearchBar.
You can nest:
navItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView: m_searchBar] autorelease];
If you get an error stating:
UISearchBars are not supported in UIBarButtonItems in non-iPad documents
adding a UISearchBar to a view within a UIBarButtonItem worked for me.

Access UI elements created in Interface Builder in the controller?

This is a very simple iPhone / Cocoa question. I have a button that transitions between two views. I set most of this up using interface builder. When I click the button and the second view is displayed, how do I programmatically change the text of the button (to say 'back', for instance)?
In your class declaration, declare a button object, and make sure it is specified as an IBOutlet:
IBOutlet UIButton* myButton;
Once you save this change, if you go back to Interface Builder, you should see this outlet when you right click on your File's Owner (assuming you have specified the File's Owner properly). Associate this outlet with the onscreen UIButton by right-click dragging.
Now the on screen object is associated with your in-code name.
Whereever you want to change the text on the UIButton, just say:
[myButton setTitle:#"Back - or whatever else you want it to say"
forState: UIControlStateNormal ];
// you can set different title text for each state
// of the button (selected, active, or normal)
Alternately, you can assign a unique tag to the control and use -[UIView viewWithTag:] to get a UIView pointer to the control. In most cases, outlets are the preferred mechanism, but tags are useful in things like table cells.
You'll need to set up an outlet for IB:
#interface MyViewController : UIViewController {
IBOutlet UIButton *myButton;
}
Save, bring up IB, set the file's owner to MyViewController, then create referencing outlets from both your UIView and UIButton to the appropriate points in the file's owner in the Connections Inspector.
Then in the implementation, you could do:
[myButton setTitle:#"Back" forState:UIControlStateNormal];
If you get lost with the connections, I'd recommend having a look at the lecture notes and video lectures at http://www.stanford.edu/class/cs193p/cgi-bin/index.php , which go into some detail about iPhone basics.
Hope that helps.
Most of the posts so far have focused on creating the button, and are very correct. The following answers the rest of the question:
When I click the button and the second view is displayed, how do I programmatically change the text of the button (to say 'back', for instance)?
The easiest way, if I understand your circumstance correctly, is to use the plug-n-play UINavigationBarController. First you want to push your second view controller onto the view stack:
// In firstViewController.m
self.navigationController = [[UIViewController alloc]initWithNibName:#"secondView" bundle:nil];
[self pushViewController:secondViewController animated:TRUE];
When your second view controller is shown, you should automatically get a back button on the left side of the nav-bar. If there is a need to change the text of that back button, you can simply refer to it like so:
// In secondViewController.m
-(void)ViewWillAppear
{
[self.navigationItem.backBarButtonItem setText:#"GoBack"];
}
There are also the left and rightBarButtonItem(s) which are handy for more complex navigation. Here is a less plug-n-play scenario:
// In secondViewController.h
-(IBAction)goBack; (this should appear as an action in your associated nib file)
// In secondViewController.m
-(void)viewDidLoad
{
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"GoBack" style:UIBarButtonItemStylePlain target:self action:#selector(goBack)];
}
-(IBAction)goBack
{
// logic to be done before going back
[self popViewControllerAnimated:secondViewController animated:TRUE];
}
You need to define and connect an "outlet". Take a look at the documentation, making note of the section on "Connections and Bindings".