深入理解 iOS 中的 AutoLayout(三)

目录

​​​​​​​前言

一、特定尺寸类别的布局

1.Size Class分类

2.Size Class的使用场景

3.Size Class 示例

4.如何检测 Size Class

5.示例代码


前言

        这篇文章继续讲解iOS中Auto Layout的高级用法。

一、特定尺寸类别的布局

        我们可以使用Size Class描述设备屏幕尺寸和界面方向的概念。它允许开发者为不同的屏幕大小和方向设计不同的布局,使得应用程序在各种设备和屏幕配置上都能呈现良好的用户界面。

1.Size Class分类

        在 iOS 中,Size Class分为两种类型:

        1.宽度 Size Class(Width Size Class) :描述屏幕的宽度。
        2.高度 Size Class(Height Size Class):描述屏幕的高度。

        每种Size Class又可以分为三种状态:

  1. 紧凑(Compact)**:表示屏幕尺寸较小或狭窄的情形,适用于 iPhone 处于竖屏状态或 iPad 处于分屏模式时的一部分屏幕。
  2. 常规(Regular)**:表示屏幕尺寸较大,适用于 iPad、iPhone Plus 设备横屏状态或 iPhone 在大屏设备上的竖屏状态。
  3. 未定义(Unspecified)**:主要在一些特定的情况下使用,表示没有指定的尺寸分类。

2.Size Class的使用场景

        在 iOS 开发中,你可以使用Size Class来适配不同的屏幕和设备,尤其是在使用 Auto Layout 时。借助Size Class,你可以为不同的设备设计不同的界面布局。例如,在 iPhone 设备上使用紧凑布局,在 iPad 设备上使用常规布局,以确保用户在不同设备上获得最佳体验。

3.Size Class 示例

        在 Interface Builder(Xcode 的界面设计工具)中,Size Class允许你为不同的设备配置单独的布局。例如,你可以为 iPhone 竖屏(Compact Width x Regular Height)设置一种布局,为 iPad 设备或 iPhone 横屏(Regular Width x Regular Height)设置另一种布局。

        例如,假设你有一个视图布局在竖屏 iPhone 上显示为单列,但在横屏或 iPad 上希望显示为双列。你可以根据不同的Size Class,为这两个场景设置不同的约束。

        Size Class 组合

        常见的 `Size Class` 组合包括:

        1.Compact Width x Compact Height: 适用于 iPhone 在横屏时的显示状态。
        2.Compact Width x Regular Heigh: 适用于 iPhone 在竖屏时的显示状态。
        3.Regular Width x Regular Height: 适用于 iPad 在横屏或竖屏时的显示状态,或者 iPhone Plus 在横屏时的显示状态。
        4.Regular Width x Compact Height: 比较少见,适用于 iPhone Plus 在横屏状态下的一些特殊情况。

4.如何检测 Size Class

        在代码中,你可以通过UITraitCollection来检测当前的Size Class,从而根据设备的屏幕尺寸和方向来调整界面布局。

        例如,在UIViewController中可以这样检测:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    
    if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact) {
        // 当前宽度 Size Class 为 Compact
    } else if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) {
        // 当前宽度 Size Class 为 Regular
    }
    
    if (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
        // 当前高度 Size Class 为 Compact
    } else if (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular) {
        // 当前高度 Size Class 为 Regular
    }
}

        这个方法会在设备方向改变或大小发生变化时被调用,从而允许你根据新的 `Size Class` 来调整布局。

5.使用 Size Class 的最佳实践

        1.为不同设备配置不同的布局:通过Size Class,你可以为 iPhone 和 iPad 等设备配置不同的界面布局。
        2.适应多任务分屏模式:在 iPad 的分屏模式下,你的应用程序界面可能需要适应不同大小的屏幕部分,Size Class可以帮助你实现这种适配。
        3. 结合 Auto Layout:Size Class 与 Auto Layout 是强大的组合,通过它们,你可以为不同设备和屏幕方向设置灵活的布局和约束。
        4. 定制控件样式:你可以为不同的Size Class定制控件的外观和样式,使得你的应用在不同设备上都有一致且良好的用户体验。

5.示例代码

        以下是一个简单的 iOS 应用 Demo,展示了如何根据不同的 Size Class 来调整界面布局。这个示例会根据设备的 Size Class 改变视图的背景颜色以及布局方式。

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UIView *topView;
@property (nonatomic, strong) UIView *bottomView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 初始化两个视图
    self.topView = [[UIView alloc] init];
    self.topView.translatesAutoresizingMaskIntoConstraints = NO;
    self.topView.backgroundColor = [UIColor redColor];
    
    self.bottomView = [[UIView alloc] init];
    self.bottomView.translatesAutoresizingMaskIntoConstraints = NO;
    self.bottomView.backgroundColor = [UIColor blueColor];
    
    [self.view addSubview:self.topView];
    [self.view addSubview:self.bottomView];
    
    // 默认布局
    [self setupConstraintsForCompactWidthAndRegularHeight];
}

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    
    // 检测Size Class并根据不同的组合更新布局
    if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact &&
        self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular) {
        
        [self setupConstraintsForCompactWidthAndRegularHeight];
        
    } else if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular &&
               self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular) {
        
        [self setupConstraintsForRegularWidthAndRegularHeight];
    }
}

#pragma mark - Constraints Setup

- (void)setupConstraintsForCompactWidthAndRegularHeight {
    // 移除所有约束
    [NSLayoutConstraint deactivateConstraints:self.view.constraints];
    
    // 竖直方向布局,两个视图上下排列
    [NSLayoutConstraint activateConstraints:@[
        [self.topView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
        [self.topView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.topView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.topView.heightAnchor constraintEqualToConstant:200],
        
        [self.bottomView.topAnchor constraintEqualToAnchor:self.topView.bottomAnchor],
        [self.bottomView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.bottomView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.bottomView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
    ]];
    
    // 更新背景颜色
    self.topView.backgroundColor = [UIColor redColor];
    self.bottomView.backgroundColor = [UIColor blueColor];
}

- (void)setupConstraintsForRegularWidthAndRegularHeight {
    // 移除所有约束
    [NSLayoutConstraint deactivateConstraints:self.view.constraints];
    
    // 水平方向布局,两个视图并排排列
    [NSLayoutConstraint activateConstraints:@[
        [self.topView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
        [self.topView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.topView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:0.5],
        [self.topView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
        
        [self.bottomView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
        [self.bottomView.leadingAnchor constraintEqualToAnchor:self.topView.trailingAnchor],
        [self.bottomView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.bottomView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
    ]];
    
    // 更新背景颜色
    self.topView.backgroundColor = [UIColor greenColor];
    self.bottomView.backgroundColor = [UIColor yellowColor];
}

@end

        在这个例子中:       

1. 视图布局

        topView 和 bottomView 是两个用于展示的视图,颜色和布局根据设备的 Size Class 改变。

2. traitCollectionDidChange: 方法

        当设备的 Size Class 发生变化时(例如从竖屏切换到横屏),系统会调用这个方法。在这里,根据不同的 Size Class 组合来选择不同的布局。

3. 布局方式

        Compact Width and Regular Height: 竖屏时,两个视图上下排列。

        Regular Width and Regular Height: 横屏时,两个视图左右排列。

4. 激活和移除约束

        在每次更新布局时,首先移除之前的约束,然后添加新的约束。这确保了布局能根据 Size Class 正确调整。

二、使用自适应大小的表视图单元格

        当我们是用UITableViewCell的时候,如果想要使用AutoLayout布局,比如设置tableView的rowHeight为UITableViewAutomaticDimension。

  1. tableView.estimatedRowHeight = 85.0
  2. tableView.rowHeight = UITableViewAutomaticDimension
  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我叫柱子哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值