iOS开发:UILabel字号根据屏幕缩放
2018-10-20 12:21
711 查看
场景:
假设我们有这样一个需求,iPhone 6(屏幕宽度为375pt)上的设计图上的字号为17pt,iPhone 6 Plus上的字号根据屏幕宽度缩放,即字号为(17pt x 414pt / 375pt)= 18.768pt
解决方案:
如果一个一个设置太麻烦,容易遗漏,这时候我们采用 runtime 的替换方法来实现,如果嫌替换方法太麻烦,我们可以用第三方库 Aspects 来辅助我们解决。
步骤:
-
添加pod
pod 'Aspects', '~> 1.4.1'
- 新建UILabel Category,命名为UILabel+AspectsScaling
以下为文件内容
UILabel+AspectsScaling.h 文件
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface UILabel (AspectsScaling) @end NS_ASSUME_NONNULL_END
UILabel+AspectsScaling.m 文件
#import "UILabel+AspectsScaling.h" #import "Aspects.h" @implementation UILabel (AspectsScaling) + (void)load { NSError * error = nil; [self aspect_hookSelector:@selector(initWithCoder:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSCoder * coder) { [info.instance scaleFont]; } error:&error]; [self aspect_hookSelector:@selector(initWithFrame:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, CGRect frame) { [info.instance scaleFont]; } error:&error]; //以下是log方法,可以不要 #if DEBUG [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info) { UILabel * label = info.instance; NSLog(@"UILabel: Before Scaling font size: %f", label.font.pointSize); } error:&error]; [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) { UILabel * label = info.instance; NSLog(@"UILabel: After Scaling font size: %f", label.font.pointSize); } error:&error]; #endif } - (void)scaleFont { CGFloat ratio = CGRectGetWidth(UIScreen.mainScreen.bounds) / (CGFloat)375; self.font = [UIFont fontWithDescriptor:self.font.fontDescriptor size:self.font.pointSize * ratio]; } @end
解释:
- 显然,这是缩放字体的方法
- (void)scaleFont;
- 这个方法是在原来的initWithCoder: 方法后面执行一个 block ,这是 Aspects 库的方法,利用的是 runtime,可以自行了解源码
[self aspect_hookSelector:@selector(initWithCoder:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSCoder * coder)...
- 再看 log 方法,这个 log 方法利用 Aspects ,在替换字体前后 NSLog 字体的字号,这个区别在参数 AspectPositionBefore 和 AspectPositionAfter
[self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info) ... [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) ...
- 我们看看 Aspects 的Aspects.h文件:
里面提供两个方法,-
一个是类方法(修改类的所有实例的方法),
- 一个是实例方法(修改单个实例的方法),
- 返回值是一个id<AspectToken>可以保存以后取消修改,
- usingBlock:(id)block 里面的类型id一般情况下可以写成^(id<AspectInfo> info, ...) ...是要修改的方法的所有参数,如@selector(initWithFrame:) ,block 类型^(id<AspectInfo> info, CGRect frame)
... typedef NS_OPTIONS(NSUInteger, AspectOptions) { AspectPositionAfter = 0, /// Called after the original implementation (default) AspectPositionInstead = 1, /// Will replace the original implementation. AspectPositionBefore = 2, /// Called before the original implementation. AspectOptionAutomaticRemoval = 1 << 3 /// Will remove the hook after the first execution. }; ... + (id<AspectToken>)aspect_hookSelector:(SEL)selector withOptions:(AspectOptions)options usingBlock:(id)block error:(NSError **)error; /// Adds a block of code before/instead/after the current `selector` for a specific instance. - (id<AspectToken>)aspect_hookSelector:(SEL)selector withOptions:(AspectOptions)options usingBlock:(id)block error:(NSError **)error; ...
总结
Aspects 是 iOS Aspect-oriented programming (AOP) 的一种实现,
满足以下几点就可以使用(但不是必须满足才能使用)
- 原来要有实例方法实现
- 频繁调用,一个一个修改太麻烦
- 在原来的实例方法的前面和后面可以插入代码完成需求
- 最最常用的是log,以后可以一步注释
[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo, BOOL animated) { NSLog(@"View Controller %@ will appear animated: %tu", aspectInfo.instance, animated); } error:NULL];
Aspects 不是万能的,GitHub项目主页有Compatibility and Limitations,一般情况下不会遇到
相关文章推荐
- iOS UILabel根据字数自适应宽高以及控件按屏幕大小按比例缩放
- iOS开发--UILabel根据内容自动调整高度
- iOS开发之----根据文本内容和字体大小计算UILabel的size
- iOS开发- 根据表格点击tableviewCell获取在当前屏幕中的坐标值
- [iOS]图组全屏可缩放和旋转屏幕来展示
- iOS开发UI篇—UIScrollView控件实现图片缩放功能
- ios开发 数组排序——根据数组内字典的指定属性排序
- iOS开发 获取控件在屏幕上的位置(坐标系转换)
- 【iOS-Cocos2d游戏开发】CCScene切换的所有特效(28种)以及设置屏幕横竖屏!
- iOS开发- UILabel 自动换行 及 高度自适应
- iOS应用开发中使用Auto Layout来适配不同屏幕尺寸
- 微信小程序开发之图片等比例缩放 获取屏幕尺寸图片尺寸 自适应
- iOS 开发:绘制像素到屏幕
- iOS字体根据不同屏幕尺寸适配
- 【iOS开发】iOS根据不同的语言,显示不同的APP名字--即:app名字多语言本地化
- Android根据屏幕宽度,按比例缩放图片(图片)
- iOS开发之 UIlabel(以后有新发现或者好的用法会补充~)
- 转--iOS开发学习 根据Debug和Release状态变化来屏蔽日志输出
- IOS开发调整UILabel的行间距
- iOS开发 强制竖屏。系统KVO 强制竖屏—>适用于支持各种方向屏幕启动时,竖屏展示广告