「OC」自动布局Masonry的运用

「OC」自动布局Masonry的运用

前言

笔者在前面写过关于OC自带的系统自动布局,自动布局的好处就是控件的位置都是相对的,这样即使在不同屏幕尺寸的手机之中的布局都是大致相同的,比frame布局来的更加智能。方便是方便但是我在使用的过程之中发现,使用系统自带的自动布局代码量多且过程繁琐,我们还需要了解在OC之中各个边的名字,这样子好像也不够方便。最近才知道有第三方库Masonry这个工具(难怪当时学习自动布局的时候,网上相关的资料很少)

自动布局

在这里顺带提一嘴frame布局和自动布局的差别

Frame布局方式在简单情况下,较为简单,而且性能极高,但是不利于扩展,当手机的尺寸不同或者横竖屏的时候布局都会有一定的问题,如果想要解决一般来说就是使用几套frame布局。反观自动布局布局,使用起来较为方便,可以轻松应对各种布局方式,但是会消耗一定的性能,使用不当容易造成性能问题。

首先我们来看使用官方自带的自动布局是如何实现的

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor orangeColor];
    view.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view];
    
    UILabel *label = [[UILabel alloc] init];
    label.backgroundColor = [UIColor redColor];
    label.text = @"AutoLayout";
    label.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:label];
    
    [NSLayoutConstraint activateConstraints:@[
       [view.topAnchor constraintEqualToAnchor: self.view.safeAreaLayoutGuide.topAnchor constant:200],
       [view.centerYAnchor constraintEqualToAnchor: self.view.centerYAnchor ],
       [view.centerXAnchor constraintEqualToAnchor: self.view.centerXAnchor ],
       [view.heightAnchor constraintEqualToConstant:300],
       [view.widthAnchor constraintEqualToConstant:180],
       
       [label.topAnchor constraintEqualToAnchor:view.topAnchor constant:30],
       [label.centerXAnchor constraintEqualToAnchor: view.centerXAnchor ],
       [label.heightAnchor constraintEqualToConstant:40],
       [label.widthAnchor constraintEqualToConstant:90]
    ]];

}


@end

代码实现的形状如下

image-20240812110732562

NSLayoutConstraint之中就是我们自动布局所需要的代码了,我们还要对控件的translatesAutoresizingMaskIntoConstraints该写为NO,可以看到NSLayoutConstraint之中的代码量还是很多的,所以这也是我们学习Masonry的原因。

Masonry的布局使用

Masonry 是一个流行的 iOS 和 macOS 开发库,用于简化系统自带的 Auto Layout 的使用。它提供了链式语法和便捷的方法,使得创建和管理视图之间的约束变得更加简单和直观。

和系统自带的自动布局比较相似的一个点,那就是Masonry也是通过约束来对控件进行相关的布局,我们使用Masonry进行布局需要以下几个方法

- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

Masonry的使用方式

我们可以将我们前面给出的官方自动布局的代码稍作转化

#import "ViewController.h"
#import "Masonry.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor orangeColor];
    view.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view];
    
    UILabel *label = [[UILabel alloc] init];
    label.backgroundColor = [UIColor redColor];
    label.text = @"AutoLayout";
    label.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:label];
    
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(200);
        make.centerY.equalTo(self.view);
        make.centerX.equalTo(self.view);
        make.height.equalTo(@300);
        make.width.equalTo(@180);
    }];
    
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(view).offset(30);
        make.centerX.equalTo(view);
        make.height.equalTo(@40);
        make.width.equalTo(@90);
    }];
}

@end

注:self.view还可以再被简化,直接用self代替,你就只管偷懒剩下就交给编译器!!!

我们可以看到,我们在创建约束的时候,都没有将对应边写出来,但是系统却帮我们给自动处理了,在这个代码·make.top.equalTo(self.view).offset(200);我们并没有指定这个view去对齐self.view的top,但是系统就进行自动对应了,十分的方便,但如果我们不要进行对应边进行对应,我们也可以使用指定边进行布局操作。

例如:我们将label对top去对应view的bottom,那么我们作出以下修改,可以得到

[label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(view.mas_bottom).offset(30);
        make.centerX.equalTo(view);
        make.height.equalTo(@40);
        make.width.equalTo(@90);
    }];

请添加图片描述

另外,我们在使用数字直接限制控件的高度和宽度的时候,一共有两种写法

make.height.mas_equalTo(40); 

make.height.equalTo(@40);

这两种方式似乎都各有繁琐的地方,那我看到网上有一个小技巧,利用宏定义,可以让代码变得更加的简洁

#define MAS_SHORTHAND_GLOBALS

[label mas_makeConstraints:^(MASConstraintMaker *make) {
   make.height.equalTo(40);
}];

说完了关于常数以及边界的内容,如果我们想要改变约束方程之中的系数,就需要用上multipliedBydividedBy这两个方法了,看到方法我们不难知道,一个是乘法一个除法,如果我们想要控件的宽度为控制器宽度的一半的话,可以用以下方法

[label mas_makeConstraints:^(MASConstraintMaker *make) {
   make.width.equalTo(self).multipliedBy(0.5);
}];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
   make.width.equalTo(self).dividedBy(2);
}];

有了系数,有了常数接下来我们就可以使用我们熟悉的约束的写法了

我们设置label的宽度为控制器尺寸的0.5倍在多20个像素点,代码如下

[label mas_makeConstraints:^(MASConstraintMaker *make) {
  make.width.equalTo(self).offset(20).multipliedBy(0.5);
}];

offset和multipliedBy的位置可以互换,不影响实现

一般来说我们的约束都是对控件的四条边进行操作的,那这样就要写四行代码,还是有一点麻烦的,那我们可以使用以下方法,再进行简化

[label mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(self).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];

以上代码我们就是将label限制在了,上左下右边距各为10,我们会发现这个set的设置与之前之前的接触的不太一样,按之前的习惯如果要设置内边距的话,其实应该是设置为(10,10,-10,-10),但是这个编译器帮我们进行了自动处理,所以就变成以上代码的内容,需要注意

Masonry的优先级

Masonry为我们提供了三个优先级的方法,priorityLow()priorityMedium()priorityHigh(),这三个方法内部对应着不同的默认优先级,当然我们也可以使用priority() 括号之中添加数字设置具体的数值。

优先级的方法相等于的数值大小
priorityLow()250
priorityMedium()500
priorityHigh()750
[label mas_makeConstraints:^(MASConstraintMaker *make) {
   make.width.equalTo(view).priorityLow();
   make.width.equalTo(@[view,@100]).priorityHigh();
   make.width.equalTo(@300).priority(888);
}];

优先级的用处是在于,如果我们在约束发生冲突的时候,而且我们也不想将约束删除的话,会优先实现优先级更高的。系统通过比较两个”相互冲突的约束”的优先级,从而忽略低优先级的某个约束,达到正确布局的目的约束优先级默认都是1000。

参考资料

浅谈Masonry的使用技巧

浅谈Constraints,Layout,Display的点点滴滴

### 回答1: 在Ubuntu上安装Node.js和npm的步骤如下: 1. 打开终端,输入以下命令更新软件包列表: ``` sudo apt-get update ``` 2. 安装Node.js和npm: ``` sudo apt-get install nodejs npm ``` 3. 验证Node.js和npm是否安装成功: ``` node -v npm -v ``` 如果输出了版本号,则说明安装成功。 4. 如果你需要安装特定版本的Node.js,可以使用nvm(Node Version Manager)来管理多个版本的Node.js。安装nvm的步骤如下: ``` curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash ``` 安装完成后,重新打开终端,输入以下命令安装指定版本的Node.js: ``` nvm install <version> ``` 其中,`<version>`是你需要安装的Node.js版本号,例如: ``` nvm install 14.17.6 ``` 安装完成后,可以使用以下命令切换到指定版本的Node.js: ``` nvm use <version> ``` 例如: ``` nvm use 14.17.6 ``` 如果需要查看已安装的Node.js版本列表,可以使用以下命令: ``` nvm ls ``` 如果需要卸载某个版本的Node.js,可以使用以下命令: ``` nvm uninstall <version> ``` 例如: ``` nvm uninstall 14.17.6 ``` ### 回答2: Node.js和npm是开发现代Web应用程序必不可少的工具。Node.js是一个基于JavaScript的运行时环境,可以在Web服务器端运行JavaScript代码,而npm则是一个Node.js软件包管理器,允许开发人员轻松地安装和管理依赖项。 在Ubuntu上安装Node.js和npm的步骤如下: 1. 打开终端并更新Ubuntu软件包列表:sudo apt-get update。 2. 安装Node.js的PPA存储库:sudo apt-get install curl && curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -。 3. 安装Node.js:sudo apt-get install nodejs。 4. 确认Node.js已经成功安装:node -v。 5. 确认Node.js的npm包已经成功安装:npm -v。 现在就可以开始使用Node.js和npm来构建和管理您的Web应用程序了。要安装其他Node.js模块,可以通过npm在终端中使用以下命令:npm install 模块名称。 需要注意的是,在安装Node.js之前,应该先安装npm。如果您尚未安装npm,可以使用以下命令来安装它:sudo apt-get install npm。 除了以上步骤,还可以通过使用nvm(Node.js版本管理器)来安装不同版本的Node.js。nvm允许开发人员轻松地安装和管理多个Node.js版本,并切换它们。 总的来说,使用Ubuntu来安装Node.js和npm非常简单。只需遵循上述步骤,您就可以开始使用这些重要的工具来构建和管理您的Web应用程序。 ### 回答3: Ubuntu 是一个非常流行的操作系统,它是一个基于 Debian 的 Linux 发行版。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它可以让我们在服务器端使用 JavaScript。npm(Node Package Manager)是 Node.js 的包管理器,它可以让我们轻松地管理和分享我们的代码包。 在 Ubuntu 上安装 Node.js 和 npm 非常简单,我们可以按照以下步骤进行操作: 1. 在终端中输入以下命令更新软件源信息: sudo apt update 2. 安装 Node.js 和 npm: sudo apt install nodejs npm 3. 验证 Node.js 和 npm 是否安装成功: node -v npm -v 如果输出的版本号与我们所安装的版本号一致,则说明安装成功。 4. (可选项)如果需要更改 npm 的默认安装路径,可以使用以下命令: npm config set prefix ~/.npm-global 这将在主目录下创建一个名为 .npm-global 的目录,并将 npm 的全局安装路径设置为这个目录。接着,我们需要将这个目录添加到 PATH 环境变量中: echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc source ~/.bashrc 这样,我们就可以使用 npm install -g 命令全局安装项目所需要的包了。 总的来说,在 Ubuntu 上安装 Node.js 和 npm 非常简单,只需要几条命令即可完成。当然,对于不同的应用场景,我们还需要了解更多的 Node.js 和 npm 相关知识,来更好地管理我们的代码包。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值