I wonder if there is a way to use constants in Interface Builder, in order to avoid manually setting the same color at different places for example (it could be a very tedious job sometimes...)
Currently I set the color in the code and use #define to setup the color, but obviously IB can't use #define...
I have worked around this issue by subclassing the various controls to ensure the same style throughout the app. The drawback is that you can not see the style in interface builder only a wireframe.
For example I have a
#interface MyButton : UIButton
#end
#implementation MyButton
-(void) initialize{
self.backgroundColor = [UIColor MyButonColor]; // Using a category on UIColor
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
[self initialize];
}
return self;
}
I think the easiest way to do this would be to create a category on the UIColor class and create a class method on it. For example:
Place this in a header file (e.g. UIColor+CustomColors.h):
#interface UIColor ( CustomColors )
+ (UIColor *)myCustomColor;
#end
Place this in an implementation file (e.g. UIColor+CustomColors.m)
#implementation UIColor ( CustomColors )
+ (UIColor *)myCustomColor
{
return [UIColor colorWithRed:0.2 green:0.5 blue:0.2 alpha:1.0];
}
#end
Then you have access to the class method anywhere in your code like so:
...
self.view.backgroundColor = [UIColor myCustomColor];
...
See Apple's documentation on Categories for more info.
Alternatively, you can save swatches of color through the system color palette. To do this you simply call up the system color palette, select a color and drag it into the grid of colors.
These colors are now available in not only every Interface Builder document you create, but any application that makes use of the system color palette.
color palette http://img.skitch.com/20091030-dhh3tnfw5d8hkynyr7e5q3amwg.png
Related
It might be a simple question yet I could not figure out what I am missing.
In ViewControl.h I declared UIColor
#property (nonatomic, strong) UIColor * myColor;
In ViewControl.m I have a method that do something and return new UIColor
#synthesize myColor = _myColor;
In ViewDidLoad Method
- (void)viewDidLoad
{
myColor = [UIColor RedColor];
}
-(void) ShowColorPopUpView
{
if (!self.wePopoverController)
{
ColorViewController *contentViewController = [[ColorViewController alloc] init];
contentViewController.delegate = self;
self.wePopoverController = [[WEPopoverController alloc] initWithContentViewController:contentViewController];
self.wePopoverController.delegate = self;
self.wePopoverController.passthroughViews = [NSArray arrayWithObject:self.navigationController.navigationBar];
[self.wePopoverController presentPopoverFromRect:self.tvTweetDetails.frame
inView:self.view
permittedArrowDirections:(UIPopoverArrowDirectionUp|UIPopoverArrowDirectionDown)
animated:YES];
} else
{
[self.wePopoverController dismissPopoverAnimated:YES];
self.wePopoverController = nil;
}
}
-(void) colorPopoverControllerDidSelectColor:(NSString *)hexColor
{
_myColor = [GzColors colorFromHex:hexColor];
[self.view setNeedsDisplay];
[self.wePopoverController dismissPopoverAnimated:YES];
self.wePopoverController = nil;
}
- (UIColor *) returnColor
{
return _myColor;
}
My Question starts here: I have two methods to change a textview font and background color
- (IBAction)btnFontColorPopUpMenu:(id)sender
{
[self ShowColorPopUpView];
tvTweetDetails.textColor = [self returnColor];
}
- (IBAction)btnTextViewBackGroundColor:(id)sender
{
[self ShowColorPopUpView];
tvTweetDetails.backgroundColor = [self returnColor];
}
The issue now is when I call the method it return it returns RED and if I call it again it returns the the BlackColor.
How Can I call the method and change the Color to the new one and then return it. I want to get the Black color directly.
I want to execute the method first then return the color but what happens is assign the color before execute the method.
I hope I made it the Question Clear.
Okay, I'll take a whack at this.
I suspect you are doing some kind of presentViewController:... method in your color changer method. That's great, but it has implications. The method you call that in continues to execute during that presentation. That means it may return, etc.
This is where the concept of delegates comes in. You may benefit from restructuring the data flows here a bit.
What I suggest (if I am correct about the presentation of a color picker UI) is that you make the following changes:
Create a #protocol ColorPickerDelegate with one method: -(void) userChoseColor:(UIColor *) color
Add a #property (weak) id<ColorPickerDelegate> delegate to your color picker view controller
make your VC here implement that protocol
Inside the delegate method, set your local property
Implement a custom setter for the local propert, and update the background color whenever the color changes.
I've got several yellow buttons created using Inteface Builder. All have the same color. Currently I declare color in each xib. Can I declared it globally and reuse across all xibs?
Not possible in Interface Builder. Do it in code, for example by creating special subclass of the button.
You could use system Color Palette to save the color, but you still need to apply it to all buttons every time you decide to change it. Or you can just use Recently Used Colors in the color chooser, but neither way is enough dynamic.
Yes, you can do this.
At the bottom of the color picker popup in Interface Builder, there's a row of squares you can use to store colors for later use. Drag a color into it from the rectangle where the current color is shown at the top of the color picker to store it, and then just click a stored color later to use it.
I don't believe there is a way to do this entirely in interface builder, unfortunately. However, you can come pretty close with a little bit of code. The best way I've found to be able to change colors throughout the app in one go is to subclass the item that you want to color (UILabel, for instance) to set the color upon initialization:
#interface HuedUILabel : UILabel
#end
#implementation HuedUILabel
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
self.textColor = [AppConfig primaryColor];
}
return self;
}
#end
Then, set the label to have a custom class in IB:
Now, when you want to change the color of all your UILabels, you can do it by changing your one color def AND you don't have to clutter your code with a bunch of appearance assignments.
Most definitely!
Create a singleton object (you can call it OksanaColor, to be cool)...
... or, if you're really lazy, a read-only UIColor property that you can access from your app delegate.
You can also add a category on UIColor, so you can use it same as when you use UIColor. For example in my App I add a new file called ApplicationColors which contains all my app colors.
#interface UIColor (ApplicationColours)
+(UIColor *)savaColor;
#end
Implementation:
#implementation UIColor (ApplicationColours)
+(UIColor *)savaColor
{
return [UIColor colorWithRed:228.0f/255.0f green:86.0f/255.0f blue:86.0f/255.0f alpha:1.0f];
}
#end
Then to use it in my app, I import the ApplicationColours.h and use the same as any other UIColor. i.e:
label.textColor = [UIColor savaColor];
Here's a very simple implementation of a named colors category for UIColor. With this code in your project, UIColor will remember any colors you want to save, and will let you access your own colors or system colors using +colorWithName:
#interface UIColor (namedColors)
+ (UIColor *) colorWithName:(NSString *) name;
+ (void) setColor:(UIColor *) color forName:(NSString *) name;
#end
static NSMutableDictionary *colorStorage;
#implementation UIColor (namedColors)
+ (NSMutableDictionary *) colorStorage
{
if (!colorStorage)
colorStorage = [[NSMutableDictionary alloc] initWithCapacity:10];
return colorStorage;
}
+ (UIColor *) colorWithName:(NSString *) name
{
UIColor *result =[[self colorStorage] valueForKey:name]; // See if we have a color with this name in the colorStorage.
if (result) return result;
SEL selector = NSSelectorFromString(name); // look for a class method whose selector matches the given name, such as "blueColor" or "clearColor".
if ([self respondsToSelector:selector] && (result = [self performSelector:selector]))
if ([result isKindOfClass:[self class]])
return result;
return nil;
}
+ (void) setColor:(UIColor *) color forName:(NSString *) name
{
[[self colorStorage] setValue:color forKey:name];
}
#end
I have a custom UITableViewCell which uses a NSAttributedString. I want it to change color when the cell is selected. How can I make the NSAttributedString have the same behavior as a UILabel with highlightedTextColor set?
I have tried to change the color at the functions setSelected and setHighlighted of the cell, but it seems that they are called to late (on touchUpInside instead of touchDown)
Thanks in advance!
UILabel subclass solution
#implementation CustomLabelHighlighted
{
NSAttributedString *savedAttributedString;
}
-(void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
if (!highlighted)
{
[super setAttributedText:savedAttributedString];
return;
}
NSMutableAttributedString *highAttributedString = [savedAttributedString mutableCopy];
NSRange range = NSMakeRange(0, highAttributedString.string.length);
[highAttributedString addAttribute:NSForegroundColorAttributeName value:self.highlightedTextColor range:range];
[super setAttributedText:highAttributedString];
}
- (void)setAttributedText:(NSAttributedString *)attributedText
{
[super setAttributedText:attributedText];
savedAttributedString = attributedText;
}
#end
Typically it's pretty simple to detect selection/highlighting and change colors depending on it. The important methods are:
-(void)setHighlighted:animated:
-(void)setSelected:animated:
note that when overriding you have to use the methods with animated:, otherwise it won't work.
When you want to change only the color, the simplest solution is to let the color to be set on the label and not on the string. Note that the attributed string is still inheriting all the properties of the UILabel.
Is there any way to How to Apply global font [new custom font] to whole application in iphone objective-c.
I know that we can use below method to set font for each label
[self.titleLabel setFont:[UIFont fontWithName:#"FONOT_NAME" size:FONT_SIZE]];
But I want to change for whole application.
Please help me if anyone know.
Apparently to change ALL UILabels altogether you will need to setup a category on UILabel and change the default font. So here's a solution for you:
Create a file CustomFontLabel.h
#interface UILabel(changeFont)
- (void)awakeFromNib;
-(id)initWithFrame:(CGRect)frame;
#end
Create a file CustomFontLabel.m
#implementation UILabel(changeFont)
- (void)awakeFromNib
{
[super awakeFromNib];
[self setFont:[UIFont fontWithName:#"Zapfino" size:12.0]];
}
-(id)initWithFrame:(CGRect)frame
{
id result = [super initWithFrame:frame];
if (result) {
[self setFont:[UIFont fontWithName:#"Zapfino" size:12.0]];
}
return result;
}
#end
Now ... in any view controller you want these custom font labels, just include at the top:
#import "CustomFontLabel.h"
That's all - good luck
Ican's solution with category might be prefered just to save the day. But avoid using category to override existing methods as apple explains:
Avoid Category Method Name Clashes
... If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime. ...
Note also that overriding -(id) init; would be safer than overriding -(id)initWithFrame:(CGRect)frame. You would not face with the problem of not receiving touch events when clicking on a label on UIButtons.
Is this what you mean?
#interface GlobalMethods
+(UIFont *)appFont;
#end
#implementation GlobalMethods
+(UIFont *)appFont{
return [UIFont fontWithName:#"someFontName" size:someFontSize];
}
#end
...
[self.titleLabel setFont:[GlobalMethods appFont]];
In case you want to do it somehow automatically (without using setFont on each control), I don't believe it's possible.
If you can limit your application – or this particular feature – to iOS 5, there’s a new API coming that lets you skin the default UI very conveniently. I can’t give you details, since they are still under NDA at the time I am writing this. Take a look at iOS 5 beta SDK to find out more.
CustomLabel.h
#import <UIKit/UIKit.h>
#interface VVLabel : UILabel
#end
CustomLabel.m
#import "CustomLabel.h"
#define FontDefaultName #"YourFontName"
#implementation VVLabel
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder: aDecoder];
if (self) {
// Initialization code
// Static font size
self.font = [UIFont fontWithName:FontDefaultName size:17];
// If you want dynamic font size (Get font size from storyboard / From XIB then put below line)
self.font = [UIFont fontWithName:FontDefaultName size:self.font.pointSize];
}
return self;
}
Im extending the UIButton Class to be able to set the font and color of the UINavigationBarButton ( from this code example: switch on the code )
I goes like this:
#interface NavBarButtonGrey : UIButton
-(id)init;
#end
#implementation NavBarButtonGrey
-(id)init {
if(self = [super init]) {
self.frame = CGRectMake(0, 0, 49.0, 30.0);
self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
UIImage *image = [UIImage imageNamed:#"greyNavButton.png"];
UIImage *stretchImage =
[image stretchableImageWithLeftCapWidth:15.0 topCapHeight:0.0];
[self setBackgroundImage:stretchImage forState:UIControlStateNormal];
self.backgroundColor = [UIColor clearColor];
[self setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];
self.titleShadowOffset = CGSizeMake(0, -1);
self.titleLabel.font = [UIFont boldSystemFontOfSize:13];
}
return self;
}
#end
This is ok, but of course not very flexible.
How do I incorporate using a typedef enum (like Apple does) for all the different
colors, fonts and sizes I would like my custom button to conform to.
The only thing I can get out of the interface files from UIKit is that it is done like this:
typedef enum {
RGCustomNavBarButtonStyleBlue,
RGCustomNavBarButtonStyleGrey,
RGCustomNavBarButtonStyleBlack,
RGCustomNavBarButtonStyleGreen,
RGCustomNavBarButtonStyleRed,
} RGCustomNavBarButtonStyle;
How to get from that and into a working implementation that takes font, size, color etc. from the values of the enum through the constructor(initWithStyle)?
Does one overload constructors in Objective C? multiple constructors?
Hope it makes sense and thank you for any help given:)
To expand on what ennuikiller said above, I was taught (Hillegass's book) to pick one initializer—usually the one with the most options, like your initWithFont:andColor:—and have the other initializers call it. That main initializer is referred to as the designated initializer.
So your code would have a fully-implemented initWithFont:andColor: that calls [super init], and then you'd also have an initWithFont: that looks something like this:
-(MyClass) initWithFont: (UIFont) font
{
[self initWithFont:font andColor:RGCustomNavBarButtonStyleBlack];
}
Then your initWithFont:andColor: would handle all the other setup and calling [super init].
You can have multiple constructors such as;
-(MyClass) initWithFont: (UIFont) font;
-(MyClass) initWithFonmt: (UIFont) font andColor: (UIColor) color;
etc.
Then call [super init] as the first line in each of your custom constructors.