How do I set a custom font for the whole application? - iphone

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;
}

Related

Can I reuse colors in Interface Builder?

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

iPhone managing reusable UIImages and UIViews

What is the best way to keep my UI constants in seperate class accesible from all controllers?
UIView, UIImage and UIColour all these images and colours create a such mess of allocations and releases in my controllers and most of them are even same. Instead of alloc/relase the same images and views, CAlayers over and over again in different classes, I want to create them once, cache them (or something like that) and easily access when needed.
I want to keep memory and my code clean.
yes , its possible
create a class like gconstants , then store all your string here in h/m files
extern NSString *const APP_TITLE;
#interface UIColor (APP)
+(UIColor *) APP_NAV_COLOR;
#end
in .m file
NSString *const APP_TITLE = #"APP Name";
#implementation UIColor (APP)
+(UIColor *) APP_NAV_COLOR { return [UIColor colorWithRed:00/256.0 green:111/256.0
blue:59/256.0 alpha:1.0]; }
#end
and in any controller declare the header file
self.title = APP_TITLE;
You could use some macro's defined in a header file which you can then include in all the appropriate implementation files, or even in your prefix.pch if you want to make them available to every file in your project.
As an example, imagine a header file called Config.h
For a shared UIColor you could add the following ...
#define SOME_CONSTANT_COLOR [UIColor colorWithRed:0.5f green:0.5f blue:0.5f alpha:0.5f]
And then you can access it the same way as you would use any other macro ...
#import "Config.h" // at the top of you implmentation file, or prefix header
someView.backgroundColor = SOME_CONSTANT_COLOR;
The same also goes for images as well ..
#define SOME_IMAGE [UIImage imageNamed:#"someImage.png"]; // In config.h
myImageView.image = SOME_IMAGE; // In implementation file

CALayer does not seem to be defined

I wanted to add rounded Rects to a UITextView as explained in How to style UITextview to like Rounded Rect text field?. However when I do this I receive an error message that the methods used there are not found. I think this is weird as they are also still in the documentation. On the other side XCode does not show anything in autocomplete on the field layer. Is this field somehow deprecated or where could be the problem?
Here the two code snippets I was using:
#interface AddItemViewController : UIViewController {
IBOutlet UITextView *detailsTextView;
}
#end
Hier will ich dann die Eigenschaften aendern.
- (void)viewDidLoad
{
[super viewDidLoad];
// add rounded rects to detailsTextView
//first leads to warning that method is unknown
[detailsTextView.layer setCornerRadius:8.0f];
// displays error that property is not found on object of type CALayer *
textView.layer.cornerRadius = 8.0f;
detailsTextView.clipsToBounds = YES;
}
Add the QuartzCore framework in your project
Include this in your .h file
#import <QuartzCore/QuartzCore.h>

Subclasses of UIButton loaded from nibs are not initialized properly

I have a very simple subclass of UIButton:
#interface MyButton : UIButton
#end
#implementation MyButton
- (id) initWithCoder:(NSCoder *)decoder
{
if (!(self = [super initWithCoder:decoder]))
return nil;
NSLog(#"-[%# initWithCoder:%#]", self, decoder);
return self;
}
#end
In Interface Builder I add a UIButton, set its button type to Rounded Rect and its class identity to MyButton.
When running, I have the following log:
-[<MyButton: 0x5b23970; baseClass = UIButton; frame = (103 242; 114 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x5b23a90>> initWithCoder:<UINibDecoder: 0x6819200>]
but the button is not a round rect button anymore.
Observed on both iOS 3.2 and iOS 4.
Is this a bug or am I missing something obvious?
Create an instance of MyButton programmatically is not an acceptable answer, thanks.
Programmatically, you instantiate a button with +[UIButton buttonWithType:] which is actually a factory that returns a subclass of UIButton. So if you derive from UIButton you actually don't derive from your round rect button class (UIRoundedRectButton) but from a generic button class. But you are not allowed to subclass from UIRoundedRectButton AFAIK since it's an internal class.
It seems to be problematic to derive from UIButton, I've seen a lot of people recommed to derive from UIControl instead and implement the drawing yourself.
But you might find these articles helpful:
How to override -drawrect in UIButton subclass?
http://www.cocoabuilder.com/archive/cocoa/284622-how-to-subclass-uibutton.html
http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/
Also, I don't know why you want to derive from UIButton, but if you want to do some customization that does not involve overwriting any other methods it might be helpful to use the fact that you can do something like this:
- (id)initWithCoder:(NSCoder *)decoder {
// Decode the frame
CGRect decodedFrame = ...;
[self release];
self = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self setFrame:decodedFrame];
// Do the custom setup to the button
return self;
}
I’m not sure if this is acceptable for your needs, but I tend to prefer to override -awakeFromNib instead of -initWithCoder: in these circumstances. Does doing this resolve the issue you’re seeing?

How to share constants between Interface Builder and the code?

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