iOS关于屏幕适配

iOS关于屏幕适配

基础

  • 有两个重要的关乎适配的方法:

- (void)layoutSubviews
- (void)viewDidLayoutSubviews

-layoutSubviews是UIView的方法。当view需要布局或重新布局的时候就会调用这个方法。例如,tableView刷新的时候,cell会重新布局,layoutSubviews就会执行;当view上添加或者移除一个子空间时,view会重新布局,这个方法也会被调用;还有当我们手动调用UIView的-layoutIfNeed方法时,通知view重新布局,-layoutSubviews也会被调用。所以UIView子空间的布局在这个方法里处理是可以的。

-layoutSubviews是UIViewController的方法,当controller的self.view需要布局或者重新布局的时候就会执行。例如,横竖屏切换的时候这个方法就会被调用。self.view上的控件在这个方法里处理。

  • Autoresizing

另外UIView有个属性Autoresizing,也与屏幕适配有些关系。查看更多

大小屏

大小屏字体、控件大小…

横竖屏切换

有些空间可能横竖屏显示效果是类似的,只是大小变化,这时候只需要在-layoutSubviews方法里直接处理。

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(0, CGRectGetHeight(self.bounds)*0.5-36*0.5, CGRectGetWidth(self.bounds),36);
}

在UI设计上,有些控件横竖屏显示不一样,横屏是一个位置,竖屏在另外一个位置,这样的可通过statusBarOrientation的变化可以定位到屏幕选择的方向。

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
    if (currentOrientation == UIInterfaceOrientationLandscapeLeft || currentOrientation == UIInterfaceOrientationLandscapeRight) {
        [self setOrientationLandscapeConstraint];
    } else {
        [self setOrientationPortraitConstraint];
    }
}
- (void)setOrientationPortraitConstraint
{
}
- (void)setOrientationLandscapeConstraint
{   
}

在基类的View的-layoutSubviews和基类的ViewController的-viewDidLayoutSubviews方法里面,通过检测statusBarOrientation的方向来确定当前是需要适配横屏还是竖屏,从而进行子控件的布局。

iOS13,statusBarOrientation属性被废弃使用了,改用windowScene.interfaceOrientation。但是需要注意的是Xcode11之后新建的项目里UIApplication.sharedApplication.delegate,即Appdelegate里没有Window这个属性,需要添加一个window属性,并在SceneDelegate里给赋值,不然UIApplication.sharedApplication.delegate会闪退。查看更多

    UIInterfaceOrientation currentOrientation = UIInterfaceOrientationUnknown;
    if (@available(iOS 13.0, *)) {
        currentOrientation = UIApplication.sharedApplication.delegate.window.windowScene.interfaceOrientation;
    } else {
        currentOrientation = UIApplication.sharedApplication.statusBarOrientation;
    }
    if (currentOrientation == UIInterfaceOrientationLandscapeLeft || currentOrientation == UIInterfaceOrientationLandscapeRight) {
        [self setOrientationLandscapeConstraint];
    } else {
        [self setOrientationPortraitConstraint];
    }

特殊机型

iPhoneX这种有刘海的和以前的iPhone6适配可能会有些差别,而且导航栏大小等会发生了变化,像这种适配我觉得从创建项目初就应该考虑到这种刘海适配的问题。

单独的页面对刘海进行适配,会用到一些相关的宏,这样可能会比较麻烦。

自定义基类ViewController的view是一个可以尝试的方案。

注意

当设置UILabel/UITextField的translatesAutoresizingMaskIntoConstraints属性设置为NO时,每次给label赋值都会调用手动布局的方法-layoutSubviews/-viewDidLayoutSubviews,这时候刷新布局会很频繁。尽量不要这么做。查看更多

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morris_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值