How to change the color of UIBarButtonItem? - iphone

I have a UIToolbar, and then add two UIBarButtonItem to items of UIToolbar. How can I change the color of UIBarButtomItem? I did't find a API in the document.

see "Changing colors of UINavigationBarButtons"
EDIT: I remove the link because the domain is down...
The is the text from google cache:
Alright, here’s another quick tip. “How to change the colors of a button on a toolbar.” Of course, this can be applied to any toolbar but I am going to demonstrate the procedure on a UINavigationBar.
The above image only shows a couple of colors. In truth, you can make the button any color that you want. Fantastic! The code is really simple to do this as well. The first thing that we want to do is open the header file for whichever object will be turning a nav bar button a different color and declare the forward class UINavigationButton. You can get this class by either iterating through the subviews of the UINavigationBar, reading its subviews class names, or by class-dumping UIKit if you have a jailbroken device.
Place the following line before your interface declaration:
#class UINavigationButton;
Now, declare a new method in the header that we will use to actually change the button’s color.
- (void)changeNavigationButtonColorToColor:(UIColor *)newColor
Or something similar to the above line of code.
Now, open up your object’s implementation file and implement the above method. Anywhere in your file, add the following method:
- (void)changeNavigationButtonColorToColor:(UIColor *)newColor {
for (UIView *view in self.navigationController.navigationBar.subviews) {
NSLog(#"%#", [[view class] description]);
if ([[[view class] description] isEqualToString:#"UINavigationButton"]) {
[(UINavigationButton *)view setTintColor:newColor];
}
}
}
As you can see above, this is actually a lot easier than it first appears to be. What we first do is set up a for loop to iterate through the subviews of the UINavigationBar using NSFastEnumeration. We then output the class name of the subview, for future reference. IF the class name is UINavigationButton, then we’ve got our view. All we do is set the tintColor property if the UINavigationButton.
That’s it, we’re done!
Alternatively, if you want a wider scope, I’d suggest creating a new UINavigationBar category and placing the button color changing method in there. This was your method can be performed by any class that uses a UINavigationBar without having to recreate the same method over and over.
Remember, a back button and a navigation button are not the same thing. You will have to color the back button separately.
And as usual, here’s a link to a sample app that demonstrates this code: NavButtonColor.zip

UIBarButtomItem has limitation in customization so you can use UIButton in place of UIBarButtonItem it will gives you more customization.

For a solution that doesn't use a private API.
You can fake it by making a UISegmentedControl look like a UIBarButtonItem.
http://fredandrandall.com/blog/2011/03/31/how-to-change-the-color-of-a-uibarbuttonitem/

Related

How to standardize look and feel across my iphone app

I'm trying to figure out how to create a standard look and feel across my iphone app.
So if I ever wanted to change the background for the UIView I would normally do something like this in all my view controllers:
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]
This becomes quite redundant and error-prone when you have like 50 UIViews to manage. And of course clients change their desired background image every 3 days or so. So my next option is to create helper files, eg:
#implementation GuiDefaultsUIView
+ (void) setDefaultProperties:(UIView *) view {
view.backgroundColor = [UIColor groupTableViewBackgroundColor];
And then manually call [GuiDefaultsUIView setDefaultProperties:self.view];
from each view controller. This works, and it's how I'm doing it now but it means that for every UI object (eg UIButton, UITableView) I'd need to call a similar function for every instance of every class.
What I would like to do is to standardize this so that I get a default look and feel which I can overwrite whenever needed. I've considered Subclassing UIView / UIButton / UITableView but that does not seem like a right way to do it. Adding categories would be nice but I dont think overriding the default methods (eg: init) would be the Right Way to go either.
So. how would you standardize your look and feel?
This is a relatively simple one ;)
You just create a custom UIViewController Subclass named MyVievControllerfor example, and inherit ViewControllers from that class.
Then in the init and viewWillAppear etc. of MyViewController, you can do your customization, just make sure to call super in your subclasses.
You can do the same for UITableViewControllers and even for UIViews, to customize drawing or set standard properties.
We do that in our Apps all the time and it works great.Categories are, in some cases, fine too, for example you can override the drawRect-Method of the UINavigationBar.
What you could do (I've done and seen it in some propjects) is make a class where you store all your constants. Then when you need them just import them and use as appropriate.
Why don't you create a Super class for all of your views?
set all the properties you need there and then make every new view that you create inherit from this super class.
Lets say that you create a UIView called "PreDesignedUIview" that has your design inside like background color etc.
then whenever you create a new view you should set:
#interface NewView : PreDesignedUIview
this will automatically set your design from PreDesignedUIview to the new view.
What is wrong with that ?
Create a Utility class that stores your background colors and images. Then use these methods to get the images/colors. When you are supposed to change, don't go and call different method fro each file, instead change the color that was being returned from the method in Utility class.

Overwriting UINavigationBar to set a default titleView

What I want to do is a navigation bar with a image on it. I have a tab controller on my main view, and inside each tab I have a UINavigationController. From inside the UIViewController that my tab/navigationController calls, I could set the titleView without much problem, doing this inside the viewDidLoad method:
self.navigationItem.titleView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mylogo.png"]] autorelease];
But, I want to replace all titles in my navigationBar for this view, and it seems ugly to repeat this everywhere. So I did this on the delegate (after linking all the Outlet stuff)
self.tabOneNavController.navigationBar.topItem.titleView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mylogo.png"]] autorelease];
Again, it worked! ok, I'm almost getting there.
But the point is, I've 5 tabs and all of them have navigationControllers inside. I reduced the code repetition from every internal view to only 5 times, but it still. It requires that I do that for the NavController of each tab.
Then I tried to extend the UINavigationBar to create my own, where I could set this in the initializer, and use it in the interface builder as the object class. But it doesn't seem to work. Here is what I did:
#implementation MyNavigationBar
- (id)init {
self = [super self];
self.tintColor = [UIColor greenColor];
self.topItem.title = #"testing please work";
return self;
}
#end
in the interface file MyNavigationBar inherits from UINavigationBar. But this didn't work. Should I overwrite other method? which one? is this a good practice?
I'm not even sure if I should add one navigationBar for each tab, as I said, I have tabs and I want to have a navigation bar / navigate inside them. By now, after a near death experience trying to figure out how the interface builder / outlets and classes work, the code is working, I just would like to make unglify it.
Thank you!
The problem of repeating code which you describe has an elegant solution. Objective-C supports something called a "category", which allows you to add methods to a class. A common use for this is to customize navigation and tab bars. In Xcode 4, you would do something like this to add a category on UINavigationBar:
Hit Command+N or open the "New File" dialog. Next, choose "Objective-C category" from the Cocoa Touch menu:
Click Next and you will be prompted to enter the name of the class that you would like to add methods to as a category. It should look something like this:
Then, you should end up with a save file dialog. A quick note about convention here. Convention is to name a category after the original class, the plus sign, and then a description of what you're adding. Here's what yours might look like:
Once you save your file, you will need get something like this:
Look at that beauty. You can now override the default drawing/init methods as well as extend the functionality of the navbar.
I'd suggest looking into the init and drawRect methods, although I don't remember which ones people use. Also, please note that while under NDA, this may change in iOS 5, so just be prepared for that possibility.
Why not define a UIViewController subclass which sets the title view via self.navigationItem.titleView and have your other view controllers extend from that class? Then you're sharing that behavior across all of your controllers without repeating the implementation.

Trying to play with the annotation and bubble callout on mkmapview

I am developing an application in iphone which deals with maps. I have many annotations. I need different images to be loaded in the callout bubble.It mean user can edit the callout it may be image and He also type text on callout bubble .How can I give give multiple action on the callout bubble .
And most important think is that this annotation must drop on the map after clicking the save button. For Example I have two class (mapview And photoview),And in photoView i have three button (chooshphoto,takephoto,usephoto)when user take photo or browse for photo and he want use this photo.When he click on usephoto button the annotation must drop after that.And display onthe mapView.
The second half of your question isn't very clear but I'll try and answer the first.
The only real customisation you can apply to the callout view for an MKAnnotation is to set the Title, subtitle labels and the left/right calloutAccessoryViews. You can set the latter to images or callOutAccessoryViewIndicators, or another UIView but it can't be taller than 32 pixels.
MKAnnontationView documentation
That's really about it I'm afraid. For anything more advanced than that, you'll have to create a custom implementation. This blog post should be helpful, I plan on building something similar myself.
MKPinAnnontationView can be set to drop on the map as you describe so as long as you're happy with the Pin image for the annontation view itself, you can simply set it's animatesDrop property to YES and it will animate onto the map when it's added.
MKPinAnnontationView documentation
EDIT: I think this is what you want;-
In your mapView controller, define a property to hold the object you want to animate.
#interface MyMapViewController {
Photo *photoToAnimate;
}
#property (nonatomic, retain) Photo *photoToAnimate;
#end
Then in your implementation file, add the following to ViewDidAppear
-(void)ViewDidAppear {
...
if (photoToAnimate) {
[mapView addAnnotation:photoToAnimate];
self.photoToAnimate = nil; // reset it for the next time
}
...
}
Then in your PhotoViewController, simply set the property on the button press
-(void)usePhotoAction {
...
mapViewController.photoToAnimate = photo;
...
}
At least that's the really simple hacky way of what I was trying to describe in the comments. ViewDidAppear will fire when the MapView re-appears and it will add the pin to itself accordingly. If you need to add more than one pin, use an array to store them and iterate through the array.
There might be better patterns for this but in short, your MapView needs to get hold of the object you want to drop somehow and then not actually do anything with it until ViewDidAppear is called.

Close tableview in ViewBasedApplication

probably a very simple question but can't find the right answer anywhere. I am using XCode 4 and working on an iphone app, which probably sums up all the info that I need to provide.
Here it is:
- I created a ViewBasedApplication
- At some point depending on the user input, I load a TableView
But now how on Earth do I add a button or something to return? Note: I can't use a NavigationBased app, that would be easier but would not work for me.
Help anyone?
If you used a UITableViewController, you may want to use a UIViewController instead. In the UIVeiwController, you can add a UITableView along with your own UINavigationBar or, if you don't want to use a UINavigationBar, you could leave room for some type of custom UIButton. Either the UINavigationBar button or your custom UIButton action could trigger a close of your UIViewController.
If you add the UIViewController as a subview, then Cyprian's [self removeFromSuperView]; would work. If you present as a modal as Jamie suggests, you could use [self dismissModalViewControllerAnimated:YES];.
Well I don't know you code but you could always call
[self removeFromSuperView];

How to tint UIBarButtonItem background color? [duplicate]

This question already has answers here:
UIToolbar tint on iOS 4
(2 answers)
Closed 3 years ago.
I have a UIToolbar that contains 2 buttons. The toolbar has a tint:
toolbar.tintColor = [UIColor colorWithRed:(102.0/255.0) green:(20.0/255.0) blue:(11.0/255.0) alpha:1];
How can I make the buttons have a similar tint color?
I found this solution preferable to those listed here: Tint UIButton and UIBarButtonItem. Unlike the accepted answer, it allows you to change the color of UIBarButtonItems independent of the UINavigationBar.
In case the link goes down in the future, the gist of it is that you create a tinted UISegmentedControl (with UISegmentedControlStyleBar) with one segment, then create a UIBarButtonItem using that as its custom view.
In iOS 5, UIBarButtonItem has a tintColor property.
The best thing to do is set the tintColor AFTER you add buttons to it, as in iOS 4.0, it no longer updates buttons added to the bars after the tintColor has been set.
see "Changing colors of UINavigationBarButtons"
EDIT: I remove the link because the domain is down...
The is the text from google cache:
Alright, here’s another quick tip. “How to change the colors of a button on a toolbar.” Of course, this can be applied to any toolbar but I am going to demonstrate the procedure on a UINavigationBar.
The above image only shows a couple of colors. In truth, you can make the button any color that you want. Fantastic! The code is really simple to do this as well. The first thing that we want to do is open the header file for whichever object will be turning a nav bar button a different color and declare the forward class UINavigationButton. You can get this class by either iterating through the subviews of the UINavigationBar, reading its subviews class names, or by class-dumping UIKit if you have a jailbroken device.
Place the following line before your interface declaration:
#class UINavigationButton;
Now, declare a new method in the header that we will use to actually change the button’s color.
- (void)changeNavigationButtonColorToColor:(UIColor *)newColor
Or something similar to the above line of code.
Now, open up your object’s implementation file and implement the above method. Anywhere in your file, add the following method:
- (void)changeNavigationButtonColorToColor:(UIColor *)newColor {
for (UIView *view in self.navigationController.navigationBar.subviews) {
NSLog(#"%#", [[view class] description]);
if ([[[view class] description] isEqualToString:#"UINavigationButton"]) {
[(UINavigationButton *)view setTintColor:newColor];
}
}
}
As you can see above, this is actually a lot easier than it first appears to be. What we first do is set up a for loop to iterate through the subviews of the UINavigationBar using NSFastEnumeration. We then output the class name of the subview, for future reference. IF the class name is UINavigationButton, then we’ve got our view. All we do is set the tintColor property if the UINavigationButton.
That’s it, we’re done!
Alternatively, if you want a wider scope, I’d suggest creating a new UINavigationBar category and placing the button color changing method in there. This was your method can be performed by any class that uses a UINavigationBar without having to recreate the same method over and over.
Remember, a back button and a navigation button are not the same thing. You will have to color the back button separately.
And as usual, here’s a link to a sample app that demonstrates this code: NavButtonColor.zip
UIBarButtonItems inherently respond to setTintColor, though it's not public API.
I have a custom UINavigationBar subclass that runs this block:
for (UIView *subview in self.subviews) {
if ([subview respondsToSelector:#selector(setTintColor:)]) {
[subview performSelector:#selector(setTintColor:) withObject:[UIColor redColor]];
}
}
Obviously replace [UIColor redColor] with the color of your choosing.
Available in iOS 5.0 and later for UIBarButtonItem:
- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
It seems to be the only current solution (IOS 9.0).
tintColor is now used for the Image Color.
Swift3
UIBarButtonItem.appearance().tintColor = UIColor.green