【OC】巧用UIStackView简化布局

news2024/9/8 23:47:52

UIStackView的运用

文章目录

  • UIStackView的运用
    • 引入
    • UIStackView的作用
    • UIStackView的属性
      • compression resistance 和 hugging
      • axis
      • alignment
      • Distribution
      • spacing
    • UIStackView的方法
    • UIStackView的示例

引入

在仿写ZARA的过程之中,我看到软件之中是有大量的按钮排列在一起的,如果自己一个一个手动将按钮给添加到主视图之中,布局就会感觉十分麻烦,为了方便操作,于是我便学习了UIStackView的相关用法来简化布局的繁琐。

UIStackView的作用

UIStackView又可以被称作堆栈视图,是一种存储视图的容器,用于简化和管理其子视图的布局和排列。

它提供了一个高效的接口用于平铺一行或一列的视图组合。对于嵌入到 StackView 的视图,我们不用再添加自动布局的约束了。UIStackView会管理这些子视图的布局,并帮我们自动布局约束。也就是说,这些子视图能够适应不同的屏幕尺寸。也就是说我们只需要去管理UIStackView本身的布局,而其中的子视图的布局可以由调控UIStackView之中的属性来进行操作。

UIStackView能对布局的代码进行化简,减少了手动添加和管理约束的工作量。而且作为一个容器,删除或者添加某一个视图时,十分便利,可以使用相关方法进行动态的操作,而且布局还会相应的进行自动布局。

另外,UIStackView 支持嵌套,我们可以将一个 Stack View 嵌套到另一个 Stack View 中,从而实现更为复杂的用户界面。(但我还未使用过)

与其他继承于``UIView`的视图不同,UIStackView 它本身不能自我渲染,比如他的 backgroundColor 是无效的,所以它注定要和 UIView 相辅相成的进行工作。它能够帮助 UIView 来处理 子View 的位置和大小等布局问题。

UIStackView的属性

compression resistance 和 hugging

compression resistance(抗压缩性)和 hugging(抗拉伸性)是 UIStackView 中的两个属性,用于控制子视图在布局过程中的压缩和拉伸行为。通常情况下,较高的值表示子视图更不容易被压缩(compression resistance)或拉伸(hugging)。

我们一般使用[view setContentHuggingPriority:(UILayoutPriority) forAxis:(UILayoutConstraintAxis)]来对其进行设置

UILayoutPriority为float类型的浮点数,具体枚举类型如下:

typedef float UILayoutPriority NS_TYPED_EXTENSIBLE_ENUM;
static const UILayoutPriority UILayoutPriorityRequired API_AVAILABLE(ios(6.0)) = 1000; // A required constraint.  Do not exceed this.
static const UILayoutPriority UILayoutPriorityDefaultHigh API_AVAILABLE(ios(6.0)) = 750; // This is the priority level with which a button resists compressing its content.
static const UILayoutPriority UILayoutPriorityDragThatCanResizeScene API_AVAILABLE(macCatalyst(13.0)) = 510; // This is the appropriate priority level for a drag that may end up resizing the window's scene.
static const UILayoutPriority UILayoutPrioritySceneSizeStayPut API_AVAILABLE(macCatalyst(13.0)) = 500; // This is the priority level at which the window's scene prefers to stay the same size.  It's generally not appropriate to make a constraint at exactly this priority. You want to be higher or lower.
static const UILayoutPriority UILayoutPriorityDragThatCannotResizeScene API_AVAILABLE(macCatalyst(13.0)) = 490; // This is the priority level at which a split view divider, say, is dragged.  It won't resize the window's scene.
static const UILayoutPriority UILayoutPriorityDefaultLow API_AVAILABLE(ios(6.0)) = 250; // This is the priority level at which a button hugs its contents horizontally.
static const UILayoutPriority UILayoutPriorityFittingSizeLevel API_AVAILABLE(ios(6.0)) = 50; 

UILayoutConstraintAxis为float类型的浮点数,具体枚举类型如下:

typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
    UILayoutConstraintAxisHorizontal = 0,
    UILayoutConstraintAxisVertical = 1
};

axis

该属性规定了UIStackView的布局方向

  • Vertical: 垂直
  • Horizontal: 水平(默认值)

alignment

子视图的对齐方式

.fill: (默认) 尽可能铺满。

.leading: 当 axis 是 vertical 的时候,按 leading 方向对齐 等价于: 当 axis 是 horizontal 的时候,按 top 方向对齐。

.top: 当 axis 是 horizontal 的时候,按 top 方向对齐 等价于: 当 axis 是 vertical 的时候,按 leading 方向对齐。

.trailing: 当 axis 是 vertical 的时候,按 trailing 方向对齐 等价于: 当 axis 是 horizontal 的时候,按 bottom 方向对齐。

bottom: 当 axis 是 horizontal 的时候,按 bottom 方向对齐 等价于: 当 axis 是 vertical 的时候,按 trailing 方向对齐。

.center:居中对齐。

Distribution

定义沿堆栈视图轴排列视图的大小和位置的布局。

  • fill: (默认值) 根据compression resistance和hugging两个 priority 布局
  • fillEqually: 均匀分布
  • fillProportionally: 按比例分布
  • equalSpacing: 等间距布局,内容大小调整
  • equalCentering: 等中间线间距布局,元素间距不小于 spacing 定义的值, 如果放不下,根据compression resistance压缩。
typedef NS_ENUM(NSInteger, UIStackViewDistribution) 
    UIStackViewDistributionFill = 0
    UIStackViewDistributionFillEqually,
    UIStackViewDistributionFillProportionally,
    UIStackViewDistributionEqualSpacing,
    UIStackViewDistributionEqualCentering,
} API_AVAILABLE(ios(9.0));

spacing

spacing 属性确定子视图之间的间距。它是一个浮点数,表示子视图之间的固定间距。默认值为0。可以根据需要调整间距大小,以实现子视图之间的空白区域。

UIStackView的方法

  • init(frame: CGRect):创建一个 UIStackView
  • init(arrangedSubviews views: [UIView]):同样是创建一个 UIStackView,但我们可以将子视图传入。views 数组里的顺序即为子视图显示的顺序。
  • addArrangedSubview(view: UIView):添加一个子视图
  • removeArrangedSubview(view: UIView):删除一个子视图
  • insertArrangedSubview(view: UIView, at stackIndex: Int):在指定位置插入一个子视图

注:如果一个元素没有被 addSubview,调用 arrangedSubviews 会自动 addSubview。当一个元素被 removeFromSuperview ,则 arrangedSubviews也会同步移除当一个元素被 removeArrangedSubview, 不会触发 removeFromSuperview,它依然在视图结构中。

UIStackView的示例

在进行仿写的过程之中,我使用UIStackView来存储按钮,相关代码如下:

- (void)setupTopBar {
    self.topBarView = [[UIView alloc] initWithFrame:CGRectZero];
    self.topBarView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.topBarView];
    
    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.text = @"ZARA";
    titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:60];
    titleLabel.textAlignment = NSTextAlignmentLeft;
    titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.topBarView addSubview:titleLabel];
    
    // 创建分类标签
    UIStackView *categoryStackView = [[UIStackView alloc] initWithFrame:CGRectZero];
    categoryStackView.axis = UILayoutConstraintAxisHorizontal;
    categoryStackView.alignment = UIStackViewAlignmentCenter;
    categoryStackView.distribution = UIStackViewDistributionFillEqually;
    categoryStackView.translatesAutoresizingMaskIntoConstraints = NO;
    for (int i = 0; i < self.categories.count; i++) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        [button setTitle:self.categories[i] forState:UIControlStateNormal];
        button.tag = i;
        [button addTarget:self action:@selector(categoryButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
        button.titleLabel.font = [UIFont systemFontOfSize:16];
        button.tintColor = [UIColor blackColor];
        [categoryStackView addArrangedSubview:button];
    }
    [self.topBarView addSubview:categoryStackView];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.topBarView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:-30],
        [self.topBarView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.topBarView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.topBarView.heightAnchor constraintEqualToConstant:150],
        
        [titleLabel.topAnchor constraintEqualToAnchor:self.topBarView.topAnchor],
        [titleLabel.leadingAnchor constraintEqualToAnchor:self.topBarView.leadingAnchor],
        [titleLabel.trailingAnchor constraintEqualToAnchor:self.topBarView.trailingAnchor],
        [titleLabel.heightAnchor constraintEqualToConstant:100],
        
        [categoryStackView.topAnchor constraintEqualToAnchor:titleLabel.bottomAnchor],
        [categoryStackView.leadingAnchor constraintEqualToAnchor:self.topBarView.leadingAnchor],
        [categoryStackView.trailingAnchor constraintEqualToAnchor:self.topBarView.trailingAnchor]
    ]];
}

以上代码实现了,五个相关按钮的布局,按钮在点击之后会切换无限视图的图片种类为对应按钮名称。

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1917075.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝卓创始人褚健:未来工厂需要一个“工业安卓”

作为国内自动控制的科学家&#xff0c;过去近三十年的时间&#xff0c;褚健教授一直服务于化工行业、炼油石化等流程工业领域。褚健表示&#xff0c;因为涉及到安全生产和环保要求&#xff0c;流程工业企业的自动化水平高一些&#xff0c;但总体来看&#xff0c;目前中国大部分…

【网络安全】SSRF 之 Azure Digital Twins Explorer

未经许可&#xff0c;不得转载。 文章目录 正文 正文 Azure Digital Twins 是一个微软下的平台服务&#xff0c;允许开发者创建和运行数字孪生模型&#xff0c;这些模型能够反映物理世界中的实体及其关系&#xff0c;通过这些模型可以进行监控、分析和预测等操作。 1、进入主…

昇思25天学习打卡营第17天|基于 MindSpore 实现 BERT 对话情绪识别

基于 MindSpore 实现 BERT 对话情绪识别 BERT介绍 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种基于Transformer架构的预训练语言模型&#xff0c;由谷歌在2018年提出。从以下6个方面来介绍BERT&#xff1a; 1. 预训练和微调&…

解决keil调试遇到的hardlfault问题

在程序开发过程中遇到的程序死机问题 导致死机的原因&#xff1a;内存溢出&#xff0c;堆栈溢出&#xff0c;数组越界&#xff0c;中断错误。。。。。。 出现这个问题&#xff0c;首先查看线程的调度关系 看最后是在哪个位置死机&#xff0c;如果rt_current_thread在main_thre…

[AI 大模型] 阿里巴巴 通义千问

文章目录 [AI 大模型] 阿里巴巴 通义千问简介模型架构发展新技术和优势示例 [AI 大模型] 阿里巴巴 通义千问 简介 阿里巴巴的 通义千问 是由阿里云开发的一款大型语言模型&#xff0c;旨在为用户提供高效、智能的自然语言处理服务。 通义千问能够处理多种语言输入&#xff0c…

麒麟服务器操作系统2303SP3安装tigervnc

原文链接&#xff1a;麒麟服务器操作系统2303SP3安装tigervnc Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在麒麟服务器操作系统2303SP3上安装TigerVNC的文章。TigerVNC是一款高性能的远程桌面查看器&#xff0c;它支持多种操作系统&#xff0c;允许用户在远…

Oracle序列迁移重建

原因&#xff1a;oracle数据导入后序列不一致 解决办法&#xff1a;从原库中导出一份最新的序列号&#xff0c;在目标库中导入 1.删除目标库该用户下的所有索引 select DROP SEQUENCE ||sequence_name || ; from dba_sequences where sequence_owner xxxxx;2.查询出所有序列…

DepthAnything(2): 基于ONNXRuntime在ARM(aarch64)平台部署DepthAnything

DepthAnything(1): 先跑一跑Depth Anything_depth anything离线怎么跑-CSDN博客 目录 1. 写在前面 2. 安装推理组件 3. 生成ONNX 4. 准备ONNXRuntime库 5. API介绍 6. 例程 1. 写在前面 DepthAnything是一种能在任何情况下处理任何图像的简单却又强大的深度估计模型。 …

汽车预约维修小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;技师管理&#xff0c;技师信息管理&#xff0c;用户预约管理&#xff0c;取消预约管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;技师信息&a…

揭秘焦虑症的“隐形杀手“:这些并发症可能悄悄来袭!

揭秘焦虑症的"隐形杀手"&#xff1a;这些并发症可能悄悄来袭&#xff01;在快节奏的现代生活中&#xff0c;焦虑症已经成为越来越多人面临的心理健康挑战。然而&#xff0c;除了广为人知的焦虑、紧张、失眠等症状外&#xff0c;焦虑症还可能引发一系列看似与焦虑无关…

每天五分钟计算机视觉:目标检测算法之R-CNN

本文重点 在计算机视觉领域,目标检测一直是一个核心问题,旨在识别图像中的物体并定位其位置。随着深度学习技术的发展,基于卷积神经网络(CNN)的目标检测算法取得了显著的进步。其中,R-CNN(Regions with CNN features)是一种开创性的目标检测框架,为后续的研究提供了重…

【高中数学/指数、对数】已知9^m=10,a=10^m-11,b=8^m-9,则ab两数和0的大小关系是?(2022年全国统考高考真题)

【问题】 已知9^m10,a10^m-11,b8^m-9,则&#xff08;&#xff09; A.a>0>b B.a>b>0 C.b>a>0 D.b>0>a 【解答】 首先注意到10^log10_11-110,8^log8_9-90&#xff0c; 问题就转化为log8_9,log9_10,log10_11谁大谁小的问题&#xff0c; 再进一步…

maven高级1——一个项目拆成多个

把原来一个项目&#xff0c;拆成多个项目。 &#xff01;&#xff01;他们之间&#xff0c;靠接口通信。 以ssm整合好的项目为例&#xff1a; 如何看拆的ok不ok 只要compile通过就ok。 拆分pojo 先新建一个项目模块&#xff0c;再把内容复制进去。 拆分dao 1.和上面一样…

可控学习综述:信息检索中的方法、应用和挑战

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

统信UOS桌面操作系统上删除系统升级后GRUB中的回滚条目与备份

原文链接&#xff1a;统信UOS删除升级后GRUB中的回滚条目与备份 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在统信UOS桌面操作系统上删除系统升级后GRUB中的回滚条目与备份的文章。在进行系统升级后&#xff0c;GRUB引导菜单中可能会出现多个回滚条目和备份…

【MySQL】常见的MySQL日志都有什么用?

MySQL日志的内容非常重要&#xff0c;面试中经常会被问到。同时&#xff0c;掌握日志相关的知识也有利于我们理解MySQL 底层原理&#xff0c;必要时帮助我们排查解决问题。 MySQL中常见的日志类型主要有下面几类(针对的是InnoDB 存储引擎): 错误日志(error log):对 MySQL 的启…

51单片机:电脑通过串口控制LED亮灭(附溢出率和波特率详解)

一、功能实现 1.电脑通过串口发送数据&#xff1a;0F 2.点亮4个LED 二、注意事项 1.发送和接受数据的文本模式 2.串口要对应 3.注意串口的波特率要和程序中的波特率保持一致 4.有无校验位和停止位 三、如何使用串口波特率计算器 1.以本程序为例 2.生成代码如下 void Uar…

【漏洞复现】Crocus系统——Download——文件读取

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 Crocus系统旨在利用人工智能、高清视频、大数据和自动驾驶技术&…