美文网首页iOS开发精进技术重塑iOS自定义控件及相关
iOS 关于字体根据不同屏幕尺寸等比适配的问题

iOS 关于字体根据不同屏幕尺寸等比适配的问题

作者: 门前有棵葡萄树 | 来源:发表于2016-03-17 22:10 被阅读31825次

背景

  • 去年的六月份开始了一个新的项目,此项目支持的设备从4S开始一直到6+,也就是说屏幕的尺寸最小的320x480 最大的1242x2208 (不过目前好像大部分的App都会这样去支持),而客户那边有一个奇葩要求 就是所有的控件布局必须依据屏幕的尺寸等比缩放。当然这个对于iOS的开发来说的话还是比较容易实现的(iOS有个Autoresizing刚好是依据父视图的大小作等比缩放的)。

  • 项目就这样愉快的进行,然而当项目快要结束的时候,客户愤怒质问我们为什么字体大小没有根据屏幕作等比适配,再有几天的时间就要上线了,直到现在才发现这种天天在眼前晃荡的问题。。。。

  • 此时我们开发的内心是崩溃的。。。 因为项目非常赶时间,客户要求17天上线第一个版本,所有跟主流程相关的功能必须实现。当时为了赶时间 加上为了做等比适配,所有视图全部是用XIB拖出来的 字体都是直接设置在视图里面 没有抽出来 现在要是做字体的等比适配的话 这种大量完全没有技术含量的体力活让人很无力

解决方法

  • 新建一个UIButton的类别 重写 load 方法 利用OC的运行时 对所有的Button Label作处理(一般有文字的大部分是 Button Label)
    代码如下
    UIButton+MyFont.h
#import <UIKit/UIKit.h>
#import <objc/runtime.h>

/**
 *  按钮
 */
@interface UIButton (myFont)

@end

/**
 *  Label
 */
@interface UILabel (myFont)

@end

UIButton+MyFont.m

#import "UIButton+MyFont.h"

//不同设备的屏幕比例(当然倍数可以自己控制)
#define SizeScale ((IPHONE_HEIGHT > 568) ? IPHONE_HEIGHT/568 : 1)

@implementation UIButton (myFont)

+ (void)load{
    Method imp = class_getInstanceMethod([self class], @selector(initWithCoder:));
    Method myImp = class_getInstanceMethod([self class], @selector(myInitWithCoder:));
    method_exchangeImplementations(imp, myImp);
}

- (id)myInitWithCoder:(NSCoder*)aDecode{
    [self myInitWithCoder:aDecode];
    if (self) {
        //部分不像改变字体的 把tag值设置成333跳过
        if(self.titleLabel.tag != 333){
            CGFloat fontSize = self.titleLabel.font.pointSize;
            self.titleLabel.font = [UIFont systemFontOfSize:fontSize*SizeScale];
        }
    }
    return self;
}


@end

@implementation UILabel (myFont)

+ (void)load{
    Method imp = class_getInstanceMethod([self class], @selector(initWithCoder:));
    Method myImp = class_getInstanceMethod([self class], @selector(myInitWithCoder:));
    method_exchangeImplementations(imp, myImp);
}

- (id)myInitWithCoder:(NSCoder*)aDecode{
    [self myInitWithCoder:aDecode];
    if (self) {
        //部分不像改变字体的 把tag值设置成333跳过
        if(self.tag != 333){
            CGFloat fontSize = self.font.pointSize;
            self.font = [UIFont systemFontOfSize:fontSize*SizeScale];
        }
    }
    return self;
}

@end

实在不好意思,前段时间有点忙 附上demo地址
https://github.com/ywdonga/FontSizeModify

相关文章

网友评论

  • zysmoon:谢谢 楼主 这个提供思路省了太多事了
    zysmoon:UITextField 等类似控件都可以是使用这个方法改字体等操作
  • 一生谦卦:交换initWithFrame方法的时候是不是不太好啊 如果是纯代码创建的话 font还没有创建啊 没有办法获取的 是不是应该使用runtime交换UIFont的 systemFontOfSize方法啊
  • 89848af90932:纯代码我试了交换UIFont的systemFontSize能代码目的,这样和xib的Label的交换方法没冲突,但是如果用户用fontWithName...那个方法的话不能适配,不知道楼主还有更好的写法没。
  • 悠闲自在的蜗牛:这个判断设备不就好了,用得找这么麻烦啊
  • 谢谢生活:哟西 使用的运行时,根据屏幕大小加减字体号吗?
  • 琥珀之剑:请问swift没有运行时怎么适配
  • 琥珀之剑:swift怎么适配字体
  • 孤独感爆棚:我设置UIView.setFontScale(1.2),那我320的屏幕,应该不会发生任何变化,屏幕变大字体才会变大,但现在我发现320的屏幕字体就变的很大了
    门前有棵葡萄树:@孤独感爆棚 哈哈,其实就是在xib加载字体之前 做了处理,将字体放大一定的倍数,对于代码设置的字体都没用的,因为代码是界面加载之后执行的
    孤独感爆棚:@门前有棵葡萄树 感觉怪怪的啊,我在你的基础上修改了代码,:blush:
    门前有棵葡萄树:@孤独感爆棚 设置1.2 就表示所有的字体都会放大1.2倍的,你要设置成 屏幕宽度/320 就可以了
  • 孤独感爆棚:总感觉哪里不对啊
  • GavinKang:写的很好,就是没有看太懂,这个只适用于XIB吗?
    门前有棵葡萄树:@iOS开发的毛毛虫 是的这个是适用于XIB 你可以自己尝试下
  • andy_xin:对于已写好的 纯代码 怎么去字体适配呢
    门前有棵葡萄树:@andy_xin 因为这个是在所有的字体加载前去做的处理,纯代码设置的字体 这个方法是不行的:joy:
  • qqzysh:你好, 有一个问题想请教一下, 现在苹果拒绝使用热更新框架的app的审核, 这样的话, 使用黑魔法, 进行字号的适配会不会被拒绝. 因为在网上有看到说使用了 method_exchangeImplementations 就被拒绝了. 希望您看到这个评论能尽快答复,不胜感激~
    qqzysh:@门前有棵葡萄树 之前是看到bang 神的blog, 下面的一个评论的用户, 说自己用了这个黑魔法, 被拒了, 然后注掉, 就通过审核了
    qqzysh:@门前有棵葡萄树 谢谢~
    门前有棵葡萄树:@qqzysh 你是看的这个帖子吗?http://www.cocoachina.com/bbs/read.php?tid-1715065.html应该是不会的 因为目前AFNetworing 3.0都有用这个方法,我们的项目用的就是AFNetworing3.0 前不久才上线的
  • 我唔知啊:似乎对TextView不起作用?无论怎么调整比例,字体大小都是12。
    清蒸鱼跃龙门:我运行起来也是这样
  • 会飞的盖伦:为什么不直接交换UIFont的方法
    门前有棵葡萄树:@会飞的盖伦 如果你是重写setFont方法,后面每次修改字体时 这个方法就会被反复调用
    会飞的盖伦:重复调用是什么鬼:flushed:
    门前有棵葡萄树:@会飞的盖伦 这样后面有重新设置字体的话就会重复调用了
  • ChardXu:@门前有棵葡萄树 你这个方法只能在初始化方法里面设置啊,假如我一个20大小的字体,4.7和5.5英寸的为20字体大小,4.0和3.5为 18,这个就不能处理了吧?求解
    门前有棵葡萄树:@穿马甲的小样 可以处理啊 在xib上面设置字体为18 当屏幕是4.7 5.5的时候 设置字体放大1.1倍就好了
  • 玫瑰花瓣的信笺:...demo怎么看不明白。直接运行看输出字体是有变化的。可是一但给控件设置font,字体大小就不会改变了。怎么给单独的控件设置字体大小?
    门前有棵葡萄树:@玫瑰花瓣的信笺 这个适用于纯xib的情况,如果代码直接修改的话会显示最后修改的字体
  • Mister志伟:字体用乘以比例不好搞吧,大的会很大,用工具类方法是不是能更精确的解决问题呢
    门前有棵葡萄树:@Mister志伟 https://github.com/ywdonga/FontSizeModify demo地址 可以自己设置比例大小
  • 跳跳虾:楼主 求份代码啊
    门前有棵葡萄树:@JakeTorres qq 329720990 嘿嘿
    53112f2ce9bd:楼主有联系方式么,求一个
    门前有棵葡萄树:@LiuWenqiang https://github.com/ywdonga/FontSizeModify demo地址
  • Jack_Liao:求纯代码demo一份,发出来好吗?
    Jack_Liao:@门前有棵葡萄树 谢谢你。。给我滴爱😄
    门前有棵葡萄树:@66e02a10bcec https://github.com/ywdonga/FontSizeModify demo地址
  • sunshine2222:这样搞,之前的布局不就乱了吗
  • 凯文Kevin21:把demo放到github上啊。。开源大法好,java保平安
    门前有棵葡萄树:@七秒小鱼人 https://github.com/ywdonga/FontSizeModify demo地址
  • bingo居然被占了:求使用方法 大神
  • ___as7:大赞..mark后看...
  • 西门吸雪:求demo
    门前有棵葡萄树:@西门吸雪 https://github.com/ywdonga/FontSizeModify demo地址
  • Zz7777777:大哥,求发一个demo出来,我们这些菜鸟需要学习啊
    Zz7777777:@门前有棵葡萄树 区github下载 兄弟
    门前有棵葡萄树:@PengJiang https://github.com/ywdonga/FontSizeModify demo地址
  • e5fb1e513efd:请问怎么用啊
  • 7fefb9bfebbf:已经可以移植到纯代码中,不过不完美,因为这要求在创建label是带外挂的方法必须实现,而且必须在setfont方法字体之后实现,这样的话改动全部代码的工作量就很大。还请想想办法
  • 7fefb9bfebbf:不了解xib,不过我将代码里的initwithcoder简单替换为initwithframe想用于纯代码的UI中,却没有起作用,还请赐教怎么将功能移植到纯代码UI中
    门前有棵葡萄树:@枢机主教 代码用这种方法还有很多缺陷,比如textView 在initWithFram方法中字体还是nil 获取不到
  • 8f2e59b2dc30:怎么用啊 求demo 943473713@qq.com 谢了
    门前有棵葡萄树:@小星哥 https://github.com/ywdonga/FontSizeModify demo地址
  • 64a11d88158a:UILabel里的交换方法没有执行,UIButton里的交换方法执行了,什么原因

    门前有棵葡萄树:@舍予520 https://github.com/ywdonga/FontSizeModify demo地址
    Jack_Liao:@舍予520 什么事交换方法啊520?这事专业术语吗?怎么没听过这个说法,请指教 :smile:
  • 91阿生:能不能出个demo, 继续麻烦楼主了!
    门前有棵葡萄树:@91阿生 https://github.com/ywdonga/FontSizeModify demo地址
  • 无畏009:想问你怎么在代码里使用呢?
    cde515a5bff4:@门前有棵葡萄树 说话的纯代码尼
    0a8af3e7abcf:@门前有棵葡萄树 楼主能不能出一个纯代码的
    门前有棵葡萄树:@陈建蕾 代码也有对应的方法,得空我在整出来😜

本文标题:iOS 关于字体根据不同屏幕尺寸等比适配的问题

本文链接:https://www.haomeiwen.com/subject/tnpclttx.html