iOS 关于全面屏适配的方案及UI在不同尺寸下适配方案

前言

全面屏刚出时,网上有说反人类。但过去这么久了,趋于技术的进步或看久了,大家也都慢慢习惯了(只是笔者还是买不起全面屏)。官方适配中文版文档也出来了。

图源:( baijiahao.baidu.com/s?id=157902… )

回想起刚开始适配全面屏用了一种暴力、并不优雅的方法,以至于后来出了XS(MAX)和XR后出了bug。所以选择一种可靠的、优雅的方案是很有必要的。如今网上关于探讨适配全面屏的文章五花八门,笔者将探究其中的各种方案。

由于笔者水平有限,眼界狭窄,难免出现疏忽的地方,希望大神提出更好的方案。

全面屏的数据

  • 顶部
    从以上两图,我们可以看出全面屏的顶部Statusbar变高了,其他部分没变。

Largetitle是iOS11中新加入的特性。当然我们开发中很少用到Largetitle。

  • 底部

全面屏底部多出了高度为34的Home Indicator 区域。

  • 分辨率(图源:blog.csdn.net/sinat_15735…
    虽然笔者买不起XStyle,但是虚拟器应该能满足适配的所有测试。所以开发中,请优先使用全面屏开发。笔者有个朋友,开发时用非全面屏,偶尔会出现忘记适配全面屏问题。如果用全面屏,开发效率将会进一步提升。毕竟界面适配全面屏的时候,很难忘记适配非全面屏。

App显示界面大小是由App启动页决定的。

记得iPhoneX刚出时,App在其上面运行显示居中,大小和6s一样,上下各有一块黑块。尝试打印出分辨率惊奇发现不是官方宣传的1124,2436。把启动页大小改了宏才达到预想效果。如果用xib,那就没什么问题。启动页用图片的话,要适配上@3x的图片。


3.宏怎么定义

宏里只要能区分开XStyle,其他高度就好说。

网上很多教程都是按照分辨率来区分。然而,根据上面我们可以发现,XStyle的分辨率并非固定。所以单纯按照分辨率是不行的。笔者一开始适配X就是这样,后来XSMax出了问题,被迫强行更新XCode10用XSMax,发现宏没写好(顺便吐槽一句,XCode10真是噩梦,又懒得下回去)。

也有旧教程是按照屏幕宽高。但根据上面数据也不是固定的,所以要注意。这两种失效宏都列在下面。

// 单纯根据分辨率
#define K_iPhoneXStyle ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)

// 单纯根据屏幕宽高
#defineK_iPhoneXStyle (KScreenWidth == 375.f && KScreenHeight == 812.f ? YES : NO) 

其实笔者很想弄出一个通用的宏,不那么怕出新机会失效的宏,但奈何实在想不到。只能照XStyle不一样的数据写出宏。下面列出的宏在XS Max时还是有效的。至于以后就说不准了,各位还是要根据新机分辨率或者宽高适当修改。

#define K_iPhoneXStyle ( (CGSizeEqualToSize(CGSizeMake(414, 896), [[UIScreen mainScreen] bounds].size)) || ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) ) 

或者

#defineK_iPhoneXStyle ((KScreenWidth == 375.f && KScreenHeight == 812.f ? YES : NO) || (KScreenWidth == 414.f && KScreenHeight == 896.f ? YES : NO)) 

还有其他的宏

#define KScreenWidth ([UIScreen mainScreen].bounds.size.width)
#define KScreenHeight ([UIScreen mainScreen].bounds.size.height)
#define K_iPhoneXStyle ((KScreenWidth == 375.f && KScreenHeight == 812.f ? YES : NO) || (KScreenWidth == 414.f && KScreenHeight == 896.f ? YES : NO))
#define KStatusBarAndNavigationBarHeight (K_iPhoneXStyle ? 88.f : 64.f)
#define KStatusBarHeight (K_iPhoneXStyle ? 44.f : 20.f)
#define KTabbarHeight (K_iPhoneXStyle ? 83.f : 49.f)
#define KMagrinBottom (K_iPhoneXStyle ? 34.f : 0.f) 

还有些宏,是适配字体或者view用的。将在后面介绍UI在不同尺寸下适配方案再提起。

#define KScaleWidth(width) ((width)*(KScreenWidth/375.f))
#define IsIphone6PSCREEN_WIDTH==414
#define SizeScale (IsIphone6P ? 1.5 : 1)
#define kFontSize(value)value*SizeScale
#define kFont(value)[UIFont systemFontOfSize:value*SizeScale] 

最后说一句,利用宏来写虽然简单,但有以下弊端。

  • 找不到能可靠性强的宏XStyle。毕竟以后的手机分辨率或者屏幕宽高肯定会变化(即使短时间内不会)。要适应新机型就要重新上线。
  • 假如以后新出的机刘海长度变了,到时又要修改宏。
  • App适配起横屏,也挺麻烦的。

即使有弊端,笔者还是觉得这么写可行。毕竟大多数App都不用支持横屏,而且屏幕短时间内不会有太大变动。


人要保持一颗活到老学到老的心,这些弊端有方法避免。

iOS11出了安全区域SafeArea这个概念,用得好可以解决以上问题。要点时间适应。

弊端是目前大多App都支持iOS11.0-,这样就要写判断版本号,代码多将近一倍。

优点也很明显

  • 如果苹果新出了新机型,不用改动代码适应的可能性非常大。这意味着不用为了适配问题上线新版本。* 横屏时顶部不会有偏移。有横屏需求的话,也许就不用为了横屏做额外适配。等以后App iOS11.0起步的时候(短时间不太可能qaq),个人感觉SafeArea将会成为主流。

但至少目前,看上去很美好,实际上适配写多一倍的代码让笔者望而生畏。


4.SafeArea

iOS7以后,苹果给UIViewController引入了topLayoutGuide 和 bottomLayoutGuide两个属性。用于表示顶部或底部的高度。根据有无显示状态栏、导航栏、tabBar返回高度。如果VC内嵌VC,内嵌的VC将视为另起的顶底坐标体系,不受原状态栏等影响。你可能听都没听过这两属性,因为开发中我们习惯直接用宏写上数值,几乎不用这两个属性。更何况那时iPhone还没有全面屏这种东西。

到了iOS11,苹果弃用了topLayoutGuide和bottomLayoutGuide两个属性。引入了safeArea代替。官方的建议是 不能被遮挡的内容和控件在安全区域范围内显示。如果视图底部有按钮,在全面屏下,请约束底部距离34,不要影响到Home功能。

  • safeAreaLayoutGuide

此属性适用于自动布局。

使用前

[NSLayoutConstraint constraintWithItem:someView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; 

使用后

[NSLayoutConstraint constraintWithItem:someView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view.safeAreaLayoutGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; 

笔者用的是Masonry。注意该属性是iOS11后出现的。因为X发布时,最低版本超过了11,所以全面屏都能用此属性。在这里可以看出,因为11不支持,这代码多了一倍。我们完全可以不用这新属性,减少一半代码爽歪歪。所以笔者目前开发还未使用。

 [testView mas_makeConstraints:^(MASConstraintMaker *make) {make.height.equalTo(@44);if (@available(iOS 11.0,*)) {make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);make.left.equalTo(self.view.mas_safeAreaLayoutGuideLeft);make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight);} else {make.top.equalTo(self.view).offset(KStatusBarHeight);make.left.equalTo(self.view);make.right.equalTo(self.view);}}]; 

笔者没有全面屏,只能展示一下热点了。该效果与用宏KStatusBarHeight一样。

(注:此手机系统12.0)

但横屏时就不一样了。宏写法会与上方有一段KStatusBarHeight距离,此方法没有。这就是笔者说的其中一个优点,然而并没有好到足够让笔者用它的程度。

最后有两个观点。

1⃣️对于在ViewController的view,推荐使用mas_safeAreaLayoutGuide。这样就能动态更改,即使横屏。

2⃣️对于在View之间的约束,推荐使用mas_left。一来没必要用safeArea,二来不用判断版本号,减少代码量。

  • safeAreaInsets

此属性适用于手动计算frame。

X竖屏时控制器view的safeAreaInsets是(44,0,34,0);横屏(0, 44, 21, 44)。

用到的是这个方法- (void)viewSafeAreaInsetsDidChange;

- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor redColor];UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0, KStatusBarHeight, KScreenWidth, 200)];testView.backgroundColor = [UIColor blackColor];[self.view addSubview:testView];self.testView = testView;
}

- (void)viewSafeAreaInsetsDidChange {[super viewSafeAreaInsetsDidChange];NSLog(@"%s", __func__);[self updateFrame];
}

- (void)updateFrame {if (@available(iOS 11.0, *)) {CGRect newFrame = self.testView.frame;newFrame.origin.x = self.view.safeAreaInsets.left;newFrame.size.width = KScreenWidth - self.view.safeAreaInsets.left - self.view.safeAreaInsets.right;self.testView.frame = newFrame;}
} 

用frame的话,不仅低于11的系统,就连高于11的系统,要适配起横屏问题都比较麻烦。

所以笔者是趋向于用约束的,见仁见智吧。


这里再贴出两篇说SafeArea的文章。

笔者很久不用xib了,贴出现成的一篇文章。


4.automaticallyAdjustsScrollViewInsets 和 contentInsetAdjustmentBehavior

  • automaticallyAdjustsScrollViewInsets:在iOS7.0以后,相对于ScrollView新增属性,默认为YES,系统会根据所在界面的astatus bar, search bar, navigation bar, toolbar, or tab bar等自动调整ScrollView的inset。```
  • (void)viewDidLoad { [super viewDidLoad]; self.title = @“我是导航条”; self.view.backgroundColor = [UIColor redColor]; UITableView *testTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight) style:UITableViewStylePlain]; testTableView.backgroundColor = [UIColor blueColor]; testTableView.delegate = self; testTableView.dataSource = self; [self.view addSubview:testTableView];

}

  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“cell”]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@“cell”]; } cell.textLabel.text = [NSString stringWithFormat:@“%ld”, (long)indexPath.row]; return cell;
    }

  • (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 20;
    }


<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b47f171f05f16~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b47f3855e7acc~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

可以看到没有改变tableView的frame,只是显示范围变了。

如果没有这个属性,我们要实现同样的效果,tableView尺寸要这样设置。当然手动修改insets也是可以的。

x = 0, y = KStatusBarAndNavigationBarHeight, width = KScreenWidth, height = KScreenHeight - KStatusBarAndNavigationBarHeight


但是要注意:这种自动调整是在ScrollView是其根视图添加的的第一个控件的时候,才会出现自动调整的效果。详情查看[automaticallyAdjustsScrollViewInsets属性](https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2F683deddd93a5 "https://www.jianshu.com/p/683deddd93a5")

* contentInsetAdjustmentBehavior

iOS11中废弃了automaticallyAdjustsScrollViewInsets,取而代之的是contentInsetAdjustmentBehavior属性。

该属性原理和automaticallyAdjustsScrollViewInsets原理相似,是为了进一步适应安全区域。

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b4a1315b83837~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

如果你需要自定义内边距,代码将变成以下这样。

if (@available(iOS 11.0, *)) {self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {self.automaticallyAdjustsScrollViewInsets = NO;
}


[contentInsetAdjustmentBehavior各个值之间的区别](https://link.juejin.cn/?target=https%3A%2F%2Fwww.cnblogs.com%2Fbiosli%2Fp%2Fios-contentInsetAdjustmentBehavior.html "https://www.cnblogs.com/biosli/p/ios-contentInsetAdjustmentBehavior.html")

链接里有这观点

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b4a06002d298e~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

* * *

最后来谈一下关于全面屏的适配方案。

* 支持横屏的App,每个界面带ScrollView的吧。
* 如果你的App最低支持iOS11.0,那么用`safeAreaLayoutGuide`约束将非常刺激。横屏基本不用管,除非排版需求不一样。
* 如果你的App要适配11.0-,不支持横屏。那么采用宏来写目前是主流。只是以后出了新类型可能要稍微修改一下宏,并且运行逐个界面检查。目前11.0起步的App毕竟少数,用`safeAreaLayoutGuide`反而要多判断版本号。看以后App支持版本号趋势吧。
* 如果你的App要适配11.0-,支持横屏。建议用约束。用frame可能写死人,自求多福吧。
* 横屏有时实在没办法解决某些问题的话,就写两套。 [关于iOS横竖屏适配](https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2F1993144ea35e "https://www.jianshu.com/p/1993144ea35e")

电话、热点状态栏问题
==========

有电话打进来、手机开了热点有连接,状态栏会变长20。虽然很多App并未对这些情况适配,但优秀的App应该要处理好。

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b54d7fd8b2fbd~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

横屏和电话热点并无直接关系。横屏状态下默认状态栏是不显示的。

当状态栏增高时,App的控制器的view将会下移20,但是高度却不变。tabBar不会有任何改变。所以如果某个界面scrollView一直到底的话,最好用约束到底部,这样调用viewWillLayoutSubviews时就会修改scrollView高度。建议不要写高度,不然会出现scrollView底部显示丢失20高度的问题。 [iOS 热点 拨打电话 适配](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Ffoolsong%2Farticle%2Fdetails%2F75726187 "https://blog.csdn.net/foolsong/article/details/75726187")

* * *

个人总结的UI在不同尺寸下适配方案
=================

这时就要说回上面提到的宏了。

#define KScaleWidth(width) ((width)(KScreenWidth/375.f))
#define IsIphone6PSCREEN_WIDTH==414
#define SizeScale (IsIphone6P ? 1.5 : 1)
#define kFontSize(value)value
SizeScale
#define kFont(value)[UIFont systemFontOfSize:value*SizeScale]


1.UILabel的适配问题

相信开发过程中都遇到过字体适配问题。

* * *

UIFont

App如果要设置全局字体,可以通过Swizzing修改。或者像以上宏一样,传进参数,修改字体大小。

看过一篇文章,淘宝在Plus机型的字体都加大成1.5倍。笔者买不起Plus机型,更不敢装淘宝这种剁手App,所以无法验证。

[iOS字体大小适配的几种方法](https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2F7a6106f952d3 "https://www.jianshu.com/p/7a6106f952d3")

* * *

本文要探究的是UILabel显示的问题。重点并不在UIFont上。

先研究UILabel。

* UILabel默认字体为\[UIFont systemFontOfSize:17\];// 每个中文文字宽度为17。但字母、数字宽度并非固定。例如1比0瘦。注意这将可能是个坑。 [iOS--UILabel字体默认宽度和高度](https://link.juejin.cn/?target=https%3A%2F%2Fwww.aliyun.com%2Fjiaocheng%2F378800.html "https://www.aliyun.com/jiaocheng/378800.html")
* `numberOfLines`只有设定了宽度约束的情况下起效。否则Label只会显示一行。
* UILabel默认垂直方向会居中显示,即当Label高度高于text高度,文字在垂直方向上居中。水平方向上`textAlignment`可以设置。<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/28/166b89e7b10b5d6b~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image)如果要设置成顶部对齐,有好几种方法。最粗暴的是用UITextView。 [iOS开发技巧 - 使UILabel中的文字吸顶(顶部对齐)](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Fu013316626%2Farticle%2Fdetails%2F71059601 "https://blog.csdn.net/u013316626/article/details/71059601"" style="margin: auto" />

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/28/166b8a4f3209f7f2~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

* `lineBreakMode`设置文字过长时省略号放哪。

label.lineBreakMode = NSLineBreakByCharWrapping;以字符为显示单位显

示,后面部分省略不显示。

label.lineBreakMode = NSLineBreakByClipping;剪切与文本宽度相同的内

容长度,后半部分被删除。

label.lineBreakMode = NSLineBreakByTruncatingHead;前面部分文字

以……方式省略,显示尾部文字内容。

label.lineBreakMode = NSLineBreakByTruncatingMiddle;中间的内容

以……方式省略,显示头尾的文字内容。

label.lineBreakMode = NSLineBreakByTruncatingTail;结尾部分的内容

以……方式省略,显示头的文字内容。

label.lineBreakMode = NSLineBreakByWordWrapping;以单词为显示单位显

示,后面部分省略不显示。


* `adjustsFontSizeToFitWidth` //设置字体大小适应label宽度
* `minimumScaleFactor`

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/28/166bb2da1e84003b~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

* `sizeToFit`

改变Label的尺寸以显示文字。需要注意的是,需要在label.text赋值后执行。如果宽高都进行了约束,那么调用sizeToFit将无效果。如果只约束了宽度,并且行数非1,那么sizeToFit会修改Label的高度;如果只约束了高度,或者行数为1,那么sizeToFit只会修改Label的宽度。如果二者皆未约束,只会修改Label宽度。

* `sizeToFit`和`adjustsFontSizeToFitWidth`的区别。

从字面上我们就能区分开,前者是改变Label的宽高,后者是改变字体大小。

反正以后做项目的时候,明确需求,我们是固定了字体的大小来适配label的宽,还是固定了label的宽来适配字体的大小,前者用sizeToFit,后者用adjustFontsToFit。

* * *

以淘宝举例。为了研究只能下这剁手App了。

se下搜iPhoneX

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b5a93498cb83c~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

6s下搜iPhoneX

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/27/166b5a96240edcd9~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

这里无视Label左边的图标(天猫、双11)。

其商品标题有两行。之前提到了,如果不作处理,Label默认垂直方向居中。如果文字长度只有一行,那会显示奇怪。所以笔者来约束的话,先做垂直方向处理,并且约束了宽度距离左边图片,距离cell.contentView右边。然后设置行数为2(或者约束高度,行数为0,lineBreakMode裁剪)。

还有一种方案是Label根据文字长度自动适配高度,并设置最大高度限制。输入框高度就用类似方案。网上搜UITextView自动高度一堆教程。笔者懒得翻就不弄了。基本原理是根据文字大小长度、Label的宽度、文字间距,算出文字高度,然后设置Label高度为 最大限制高度与文字高度 较小者。

再来看价格和付款人数Label。

笔者设计的话,会采用以下形式。

priceLabel.font = …[priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(imageView.mas_right).offset(…);make.height.equalTo(…);make.top…;}];numberOfPeopleLabel.font = …[numberOfPeopleLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(priceLabel.mas_right).offset(…);make.height.equalTo(…);make.top…;}];


然后在cell设置model时

priceLabel.text = …[priceLabel sizeToFit];numberOfPeopleLabel.text = …[numberOfPeopleLabel sizeToFit];


* * *

总结一下,开发中很少会用到`adjustsFontSizeToFitWidth`,大多数时候都会顶部对齐、换行、裁剪,或设置自动高度。

* * *

2.UI在不同尺寸的适配

来说最后一个非常有用的宏。

#define KScaleWidth(width) ((width)*(KScreenWidth/375.f))


笔者遇到的设计师给的图都是i6屏幕,其宽度为375.f。如果给的图不是,那么将这个宏数值修改即可。

这个宏有什么用呢?

其实就是一个比例转换的问题。不同屏幕下,某些UI可能大小不一样,这时候采用这个宏将会非常方便。

还是举回上面的两张淘宝图例子。

笔者目测(目测而已),cell是不同高度的。假如6s中商品图的宽度150.f,占屏宽0.4。在se中按照比例,320 \* 0.4,为128。

那么我们用这个宏,就能一步到位。KScaleWidth(150),在6s中就为150,在se中为128。

除此之外,间距约束用这个宏也有奇效。

这个宏在collectionView中更显神威。

<img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/10/29/166bb9613f3a7380~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image" style="margin: auto" />

设计图算好了两个cell的间距,每个cell的大小,整个collectionView的大小,contentInset。这时我们采用这个宏,在不同屏幕下的适配问题将迎刃而解。

这里为什么不写出KScaleHeight呢?

笔者并不是说不能用,只是view通常是被宽度所限制。你见过微信的cell文本内容高度有变化吗hhhhh。就像图片尺寸变了,高度也是被图片宽度带动,而不是屏幕高度。

当然此宏虽很有用,但是开发中还是要经过考虑哪些地方需要用。

* * *

参考
==

* [有关iOS11和iPhoneX的适配问题](https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2Fa4e778c2236e "https://www.jianshu.com/p/a4e778c2236e")
* [iOS之UILabel详解](https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2Fd7cb38ec2209 "https://www.jianshu.com/p/d7cb38ec2209")
* [UILabel的minimumScaleFactor](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Fjf200614379%2Farticle%2Fdetails%2F50888078 "https://blog.csdn.net/jf200614379/article/details/50888078")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值