Xcode: How to change all fonts at once in an app?

2019-05-06 15:09发布

问题:

I was wondering if it was possible to change the fonts on about 100 different viewcontrollers all at once? It would be a lot eisier than going through one by one and changing them. Any ideas? Thank you!

回答1:

The user interface files (*.xib) are plain text and you can load them into an editor.

In Xcode4 on the left pane you can right-click > open as > source.

This will give you the XML source any you can find/replace there.

Warning: doing something wrong may render the whole file useless, so unless you have source control anyway, make copies of the XIB before attempting changes.



回答2:

you cant change all the fonts at once....

But i have find one more varient that will help you...

I have made some recursive functions thy can help you..

follow following steps..

First create a class(BaseViewController) extended from UIViewController like in BaseViewController.h file

@interface BaseViewController : UIViewController

And in BaseViewController.m file write following code.

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self changeFontsOfViewController];
}

-(void)changeFontsOfViewController
{
    UIViewController * vv = [self viewControllerOfView:self.view];
    NSArray *objects = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([vv class]) owner:vv options:nil];

    for (id object in objects)
    {
        [self changeFontOfView:object];
    }

}

-(void)changeFontOfView:(UIView *)aView
{
    for (UIView *vv in [aView subviews])
    {

        if ([vv isKindOfClass:[UIButton class]])
        {
            UIButton *btn = (UIButton *)vv;
            CGFloat fontSize = btn.titleLabel.font.pointSize;
            btn.titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:fontSize];
        }
        else if ([vv isKindOfClass:[UILabel class]])
        {
            UILabel *lbl = (UILabel *)vv;
            CGFloat fontSize = lbl.font.pointSize;
            [lbl setFont:[UIFont fontWithName:@"Helvetica-Bold" size:fontSize]];
        }
        else if ([vv isKindOfClass:[UITextView class]])
        {
            UITextView *txt = (UITextView *)vv;
            CGFloat fontSize = txt.font.pointSize;
            [txt setFont:[UIFont fontWithName:@"Helvetica-Bold" size:fontSize]];
        }
        else if ([vv isKindOfClass:[UITextField class]])
        {
            UITextField *txt = (UITextField *)vv;
            CGFloat fontSize = txt.font.pointSize;
            [txt setFont:[UIFont fontWithName:@"Helvetica-Bold" size:fontSize]];
        }
        else if ([vv isKindOfClass:[UIView class]]||[vv isKindOfClass:[UIScrollView class]])
        {
            if (aView.subviews.count == 0)return;
            [self changeFontOfView:vv];
        }
    }

}

Now your every viewController(RootViewController) will be extended from BaseViewController class like in RootViewController.h..

#import "BaseViewController.h"

@interface RootViewController : BaseViewController
{

}

And make sure that you have written following in your .m file of your UIViewController(RootViewController.m)

- (void)viewDidLoad
{
    [super viewDidLoad];
}

Please follow above steps carefully you will rock.......



回答3:

How about this little recursive method on UIView?

@implementation UIView (JPCSetFont)

- (void)jpc_setAllFonts:(UIFont *)font
{
    if ([self respondsToSelector:@selector(setFont:)]) {
        UIFont *oldFont = [self valueForKey:@"font"];
        UIFont *newFont = [font fontWithSize:oldFont.pointSize];
        [self setValue:newFont forKey:@"font"];
    }

    for (UIView *subview in self.subviews) {
        [subview jpc_setAllFonts:font];
    }
}

@end


回答4:

Code by John Cromartie is a good stuff. Simple and laconic.

Just keep in mind some fonts are bold or italic. So you probably have to pass 2 (or 3) params: for regular font (as it is now), for bold font and for the italic one. Besides you have to detect if the current font is bold, etc. So there is a bit enhanced piece of code below.

However, it can work wrong on iOS7 because user can set his own fonts and, as a result, weight / style detection won't work properly.

@implementation UIView (JPCSetFont)

- (void)jpc_setAllFonts:(UIFont*)regular bold:(UIFont*)bold
{
    if ([self respondsToSelector:@selector(setFont:)]) {
        UIFont *oldFont = [self valueForKey:@"font"];

        UIFont *newFont;
        // for iOS6
        NSRange isBold = [[oldFont fontName] rangeOfString:@"Bold" options:NSCaseInsensitiveSearch];
        // for iOS7 (is device owner didn't change it!)
        NSRange isMedium = [[oldFont fontName] rangeOfString:@"MediumP4" options:NSCaseInsensitiveSearch];
        if (isBold.location==NSNotFound && isMedium.location==NSNotFound) {
            newFont = [regular fontWithSize:oldFont.pointSize];
        } else {
            newFont = [bold fontWithSize:oldFont.pointSize];
        }

        // TODO: there are italic fonts also though

        [self setValue:newFont forKey:@"font"];
    }

    for (UIView *subview in self.subviews) {
        [subview jpc_setAllFonts:regular bold:bold];
    }
}

@end

https://github.com/iutinvg/ZZLib/blob/master/ZZLib/UIView%2BZZFontSetter.h https://github.com/iutinvg/ZZLib/blob/master/ZZLib/UIView%2BZZFontSetter.m