草庐IT

Objective-C的UIStackView学习笔记

寻心_0a46 2023-03-28 原文

UIStackView

UIStackView能够利用自动布局的功能,创建能够动态适应设备方向、屏幕大小和可用空间中任何更改的用户界面。UIStackView管理其arrangedSubviews属性中所有视图的布局。这些视图是根据它们在arrangedSubviews数组中的顺序沿堆栈视图的轴线排列的。具体布局因UIStackView的轴线、分布、对齐、间距和其他特性而异。我们负责定义UIStackView的位置和大小(可选),UIStackView管理其内容的布局和大小。

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *redButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [redButton setTitle:@"红色按钮" forState:UIControlStateNormal];
    redButton.backgroundColor = [UIColor redColor];
    
    UIButton *greenButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [greenButton setTitle:@"绿色按钮" forState:UIControlStateNormal];
    greenButton.backgroundColor = [UIColor greenColor];

    UIButton *blueButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [blueButton setTitle:@"蓝色按钮" forState:UIControlStateNormal];
    blueButton.backgroundColor = [UIColor blueColor];
    
    UIStackView *stackView = [[UIStackView alloc]initWithArrangedSubviews:@[redButton,greenButton,blueButton]];
    stackView.backgroundColor = [UIColor yellowColor];
    stackView.alignment = UIStackViewAlignmentCenter;
    stackView.axis = UILayoutConstraintAxisHorizontal;
    stackView.distribution = UIStackViewDistributionFill;
    [self.view addSubview:stackView];
    
    stackView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addConstraints:@[
        [stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
        [stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
    ]];
}

显示如下:

截屏2022-04-01 上午9.31.26.png

当设置蓝色视图隐藏时,显示如下:

截屏2022-04-01 上午9.36.28.png

当修改UIStackView约束,限制UIStackView大小时,显示如下:

stackView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraints:@[
     [stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
     [stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
     [stackView.heightAnchor constraintEqualToConstant:100],
     [stackView.widthAnchor constraintEqualToConstant:300],
 ]];
截屏2022-04-01 上午10.08.52.png

当修改子视图约束,限制子视图大小时,显示如下:

stackView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addConstraints:@[
        [stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
        [stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
    ]];
    
    redButton.translatesAutoresizingMaskIntoConstraints = NO;
    [stackView addConstraints:@[
        [redButton.heightAnchor constraintEqualToConstant:50],
        [redButton.widthAnchor constraintEqualToConstant:100],
    ]];
    
    greenButton.translatesAutoresizingMaskIntoConstraints = NO;
    [stackView addConstraints:@[
        [greenButton.heightAnchor constraintEqualToConstant:50],
        [greenButton.widthAnchor constraintEqualToConstant:80],
    ]];
    
    blueButton.translatesAutoresizingMaskIntoConstraints = NO;
    [stackView addConstraints:@[
        [blueButton.heightAnchor constraintEqualToConstant:50],
        [blueButton.widthAnchor constraintEqualToConstant:120],
    ]];
截屏2022-04-01 上午10.43.49.png

既限制UIStackView约束,又限制子视图约束时,至少有一个子视图可以由UIStackView进行调整,显示如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *redButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [redButton setTitle:@"红色按钮" forState:UIControlStateNormal];
    redButton.backgroundColor = [UIColor redColor];
    
    UIButton *greenButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [greenButton setTitle:@"绿色按钮" forState:UIControlStateNormal];
    greenButton.backgroundColor = [UIColor greenColor];

    UIButton *blueButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [blueButton setTitle:@"蓝色按钮" forState:UIControlStateNormal];
    blueButton.backgroundColor = [UIColor blueColor];
    
    UIStackView *stackView = [[UIStackView alloc]initWithArrangedSubviews:@[redButton,greenButton,blueButton]];
    stackView.backgroundColor = [UIColor yellowColor];
    stackView.alignment = UIStackViewAlignmentCenter;
    stackView.axis = UILayoutConstraintAxisHorizontal;
    stackView.distribution = UIStackViewDistributionFill;
    [self.view addSubview:stackView];
    
    stackView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addConstraints:@[
        [stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
        [stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
        [stackView.heightAnchor constraintEqualToConstant:100],
        [stackView.widthAnchor constraintEqualToConstant:200],
    ]];
    
    redButton.translatesAutoresizingMaskIntoConstraints = NO;
    [stackView addConstraints:@[
        [redButton.heightAnchor constraintEqualToConstant:50],
        [redButton.widthAnchor constraintEqualToConstant:80],
    ]];
    
    greenButton.translatesAutoresizingMaskIntoConstraints = NO;
    [stackView addConstraints:@[
        [greenButton.heightAnchor constraintEqualToConstant:50],
        [greenButton.widthAnchor constraintEqualToConstant:80],
    ]];
    
    blueButton.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *blueButtonWidthAnchor = [blueButton.widthAnchor constraintEqualToConstant:120];
    blueButtonWidthAnchor.priority = UILayoutPriorityDefaultLow;
    [stackView addConstraints:@[
        [blueButton.heightAnchor constraintEqualToConstant:50],
        blueButtonWidthAnchor,
    ]];
}
截屏2022-04-01 下午4.37.00.png

UIStackView就像一个自动适应其子视图约束或管理其子视图约束的容器视图,可以大量的节省设置或更新约束的代码。我们需要在某一方面放权给UIStackView,如果我们严格限制UIStackView的约束,就应当给予UIStackView自动调整其子视图约束的权力,如果我们严格限制其子视图约束,就应当给予UIStackView自动调整自身约束的权力,如果我们既严格限制UIStackView的约束,又严格限制其子视图约束,我们会得到约束冲突,这是来自UIStackView的抗议。

常用属性

@property(nonatomic) UILayoutConstraintAxis axis;

属性描述设置UIStackView排列视图时所沿的轴线方向。UILayoutConstraintAxis提供了两个枚举值,UILayoutConstraintAxisHorizontal(水平排列)与UILayoutConstraintAxisVertical(垂直排列),默认为UILayoutConstraintAxisHorizontal。

  • UILayoutConstraintAxis提供的枚举值:
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
    //水平排列
    UILayoutConstraintAxisHorizontal = 0,
    //垂直排列
    UILayoutConstraintAxisVertical = 1
};
@property(nonatomic) UIStackViewDistribution distribution;

属性描述设置UIStackView沿指定轴线方向布局子视图的方式

  • UIStackViewDistribution提供的布局子视图的方式如下:
typedef NS_ENUM(NSInteger, UIStackViewDistribution) {
    
    /* 一种布局,其中UIStackView调整其排列的视图的大小,以便它们沿着UIStackView的轴线方向填充可用空间。
       当排列的视图不适合(上溢) UIStackView时,它会根据视图的抗压优先级缩小视图。
       如果排列的视图没有填充(下溢) UIStackView时,它会根据视图的拥抱优先级拉伸视图。
       如果存在任何歧义,UIStackView将根据排列的子视图数组中的索引调整排列的视图的大小。
       即将UIStackView填充满。
   */
    UIStackViewDistributionFill = 0,
    
    /*一种布局,其中堆栈视图调整其排列视图的大小,以便它们沿着UIStackView的轴线方向均匀的填充可用空间。
      即子视图以相同大小填充UIStackView
    */
    UIStackViewDistributionFillEqually,
    
    /* 一种布局,其中堆栈视图调整其排列视图的大小,以便它们沿着UIStackView的轴线方向按比例调整大小填充可用空。
      即子视图以比例大小填充UIStackView。
     */
    UIStackViewDistributionFillProportionally,
    
    /* 一种布局,其中UIStackView定位其排列视图,以便它们沿着UIStackView的轴线方向填充可用空间。
       当排列的视图没有填充UIStackView时(下溢),它会均匀地填充视图之间的间距。
       如果排列的视图不适合UIStackView时(上溢),它会根据视图的抗压优先级缩小视图。
       如果存在任何歧义,堆栈视图将根据视图在arrangedSubviews数组中的索引缩小视图。
       即子视图等间距填充UIStackView,间距为UIStackView调整,spacing属性限制了最小间距,但不限制最大间距。
     */
    UIStackViewDistributionEqualSpacing,
    
    /* 一种布局,试图定位排列视图,使其沿UIStackView的轴线方向具以相等的中心间距填充可用空间。
        当排列的视图没有填充UIStackView时(下溢),如果未设置spacing属性,则自动插入间距,并调整间距以满足排列的子视图有相等的中心间距。
        如果设置spacing属性,在维持以spacing属性设置间距值为最小间距的同时,它会根据视图的抗压优先级缩小视图以满足排列的子视图有相等的中心间距。
        当排列的视图不适合UIStackView时(上溢),如果未设置spacing属性,它会根据视图的抗压优先级缩小视图以满足排列的子视图有相等的中心间距。
        如果设置spacing属性,在维持以spacing属性设置间距值为最小间距的同时,它会根据视图的抗压优先级缩小视图以满足排列的子视图有相等的中心间距。
        即子视图等中心间距填充UIStackView,间距为UIStackView调整,spacing属性限制了最小间距,但不限制最大间距。
     */
    UIStackViewDistributionEqualCentering,
} API_AVAILABLE(ios(9.0));
@property(nonatomic) UIStackViewAlignment alignment;

属性描述UIStackView排列的子视图的对齐方式,其对齐方式受UIStackView排列视图时所沿的轴线方向影响。

  • UIStackViewAlignment提供的对齐子视图的方式如下:
typedef NS_ENUM(NSInteger, UIStackViewAlignment) {
    /* 填充式布局,如果UIStackView为水平排列,则子视图顶部与底部对齐UIStackView。
       如果UIStackView为垂直排列,则子视图前部与后部对齐UIStackView。
     */
    UIStackViewAlignmentFill,
    
    /* 前部对齐式布局,UIStackView为垂直排列有效。
     */
    UIStackViewAlignmentLeading,
    /* 顶部对齐式布局,UIStackView为水平排列有效。
     */
    UIStackViewAlignmentTop = UIStackViewAlignmentLeading,
    /*按照第一个子视图的第一行文文本基线对齐,且高度最大的子视图底部对齐。UIStackView为水平排列有效。
    */
    UIStackViewAlignmentFirstBaseline, 
    
    /* 子视图沿轴线方向剧中对齐
     */
    UIStackViewAlignmentCenter,
    
    /* 后部对齐式布局,UIStackView为垂直排列有效。
     */
    UIStackViewAlignmentTrailing,
    /*底部对齐式布局,UIStackView为水平排列有效。
    */
    UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing,
    /*按照第一个子视图的最后一行文文本基线对齐,且高度最大的子视图顶部对齐。UIStackView为水平排列有效。
    */
    UIStackViewAlignmentLastBaseline, // Valid for horizontal axis only
} API_AVAILABLE(ios(9.0));
@property(nonatomic) CGFloat spacing;

属性描述UIStackView排列子视图相邻边之间的间距。此属性定义了UIStackViewDistributionFill、UIStackViewDistributionFillEqually、UIStackViewDistributionFillProportionally布局的排列视图之间的严格间距,UIStackViewDistributionEqualSpace和UIStackViewDistributionEqualCenter布局的最小间距。使用负值允许重叠。默认值为0.0。

@property(nonatomic,getter=isBaselineRelativeArrangement) BOOL baselineRelativeArrangement;

属性描述一个布尔值,默认值为NO,用于确定是否从视图的基线测量视图之间的垂直间距。如果为YES,视图之间的垂直间距将从基于文本的视图的最后一条基线到其下方视图的第一条基线进行测量。顶部和底部视图的定位也使其最近的基线距离堆栈视图的边缘指定的距离。此属性仅由垂直排列的UIStackView视图使用。水平排列的UIStackView可以使用alignment属性控制。

@property(nonatomic,getter=isLayoutMarginsRelativeArrangement) BOOL layoutMarginsRelativeArrangement; 

属性描述如果为YES,UIStackView将相对于其布局边距布局其排列视图。如果为NO,它将相对于其边界布置排列的视图。默认为NO。

@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *arrangedSubviews;

属性描述由UIStackView排列的视图数组。UIStackView确保了arrangedSubviews数组总是它的子视图数组(subviews)的一个子集。每当调用addArrangedSubview:方法时,如果尚未添加该子视图,UIStackView都会将该视图添加为子视图,每当调用removeFromSuperview:方法时,UIStackView也会将其从arrangedSubviews中删除。

常用函数

- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

函数描述 :初始化UIStackView。

- (instancetype)initWithArrangedSubviews:(NSArray<__kindof UIView *> *)views;

函数描述返回管理所提供的视图的UIStackView对象。UIStackView将所有需要排列的视图添加到其arrangedSubviews组中,并这些视图添加为子视图。如果arrangedSubviews数组中包含的任何视图收到removeFromSuperview的方法调用,UIStackView也会将其从arrangedSubviews中删除。

参数 :

views :要由UIStackView排列的视图数组。

返回值 : 一个新的UIStackView对象。

- (void)addArrangedSubview:(UIView *)view;

函数描述将视图添加到arrangedSubviews数组的末尾。UIStackView确保了arrangedSubviews数组总是它的子视图数组(subviews)的一个子集。如果尚未添加该子视图,此方法会自动将提供的视图添加为UIStackView的子视图,如果已经添加该子视图,此函数不做操作。

参数 :

view : 要添加到由UIStackView排列的视图数组中的视图。

- (void)removeArrangedSubview:(UIView *)view;

函数描述此方法从UIStackView的arrangedSubviews数组中删除提供的视图。视图的位置和大小将不再由堆栈视图管理。但是,此方法不会从堆栈的子视图数组中(subviews)删除提供的视图,因此视图仍然显示为视图层次的一部分,视图仍显示在屏幕上,需要通过调用视图的removeFromSuperview方法从子视图数组中显式删除视图。

- (void)insertArrangedSubview:(UIView *)view atIndex:(NSUInteger)stackIndex;

函数描述将提供的视图添加到排列的子视图数组中指定的索引处。如果索引已被占用,UIStackView会增加arrangedSubviews数组的大小,并将其被占用的索引及被占用的索引以上位置的所有内容移动到数组中更高的空间(索引后移),然后UIStackView将提供的视图存储在索引处。如果插入的视图尚未添加到UIStackView,此方法会自动将提供的视图添加为UIStackView的子视图,但插入的索引位置仅影响arrangedSubviews数组中视图的顺序,它不会影响子视图数组(subviews)中视图的顺序,也就是说插入的视图仍旧添加到子视图数组(subviews)的末尾。

参数 :

view : 要插入到由UIStackView排列的视图数组中的视图。

stackIndex : 其在arrangedSubviews数组中插入新视图的索引,此值不得大于此数组中当前的视图数,如果索引超出范围,此方法将抛出NSInternalInconsistencyException异常。

- (void)setCustomSpacing:(CGFloat)spacing afterView:(UIView *)arrangedSubview API_AVAILABLE(ios(11.0),tvos(11.0));

函数描述 :水平排列时,在指定视图后缘应用自定义间距。垂直排列时,在指定视图下缘应用自定义间距。

参数 :

spacing : 自定义间距。

arrangedSubview : 指定视图。

- (CGFloat)customSpacingAfterView:(UIView *)arrangedSubview API_AVAILABLE(ios(11.0),tvos(11.0));

函数描述 :水平排列时,返回指定视图后缘应用自定义间距。垂直排列时,返回指定视图下缘自定义间距。

参数 :

arrangedSubview : 指定视图。

有关Objective-C的UIStackView学习笔记的更多相关文章

  1. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  2. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  3. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  4. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  5. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  6. ruby - 我如何学习 ruby​​ 的正则表达式? - 2

    如何学习ruby​​的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby​​的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/

  7. 深度学习12. CNN经典网络 VGG16 - 2

    深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG

  8. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  9. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

  10. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

随机推荐