Masonry源代码分析

ios开发模仿CocoaChina精选代码使用masonry计算cell的高度总结 http://code.cocoachina.com/view/128541        这是来自于cocoachina的精选代码,于是我就以学习的目的去自己去实现这个功能敲了一遍,因为我没用过masonry这个第三方框架,一直听朋友说,这个比较好用。但是cocoachina的源代码有个问题一只困扰着我,源代码在运行后,滑动tableView,内存将无限增大。我就看了一下他创建cell的源 阅读详情
使用Autolayout也有一段时间了,auto layout的基本概念非常简单,都是围绕约束进行的,API更是只有两个,但是使用起来感觉很麻烦。最近看到我们这边其他部门的应用使用了很多Masonry来处理UI,看起来非常清爽,链式调用看起来非常容易阅读,使用起来非常方便。但是这种之前ASI给的教训非常深刻,尤其这种大规模基础性地使用第三方开源库,需要确保可控才敢用,至少可以读懂代码并且能够局部优化代码,这是我认为的可控。尤其是这种非常基础的类库,会分布在各个模块之中,一旦出现不兼容,几乎是无法重写的。于是花了一两天时间,把这个代码研究了一下,发现比我想象中要好一些,代码设计地也非常简洁巧妙。

一. 源文件说明

1. MASConstraint: 这个是虚类是用来实现链式调用的父类。MASConstraint子类可以用来表示单独的一个NSLayoutConstraint约束(MASViewConstraint)或者一组NSLayoutConstraint约束(MASCompositeConstraint)。

2. MASConstraint+Private.h: 用于隐藏MASConstraint的私有方法,这些私有方法不会被外部调用者获取,但是类库内部却可以得到,这是个很好的设计模式,在继承中相当于protected。通过定义了较为重要的MASConstraintDelegate代理。

3. MASCompositeConstraint: 这个类用于表示一组NSLayoutConstraint约束,内部包含一个MASViewConstraint的数组做为childs。当调用这个类的类似equalTo或者install等方法的时候,这个类就会调用它的childs所对应的方法。这个类相当于一个MASViewConstraint容器,用于可以方便进行多个属性的操作,可以大大减少工作量。

4. MASViewConstraint:这个是Masonry DSL语法的核心解析类,用来表示对应NSLayoutConstraint,并将表示的属性在install的时候解析为对应的NSLayoutConstraint类,并加入到对应View中。

5. MASConstraintMaker: 这个是整个DSL过程的控制中心,控制整个添加过程。MASViewConstraint和NSCompositeConstraint都在这个maker中生成,maker并且会管理这些constraint的引用,在合适的时候,将这些constraint解析出来。重要的核心方法是实现了 MASConstraintDelegate 中的这些方法,这几个方法中是生成constraint的核心方法。注意,NSViewConstraint类如果没有加入到NSCompositeConstraint中,它的MASConstraintDelegate是maker;如果它是NSCompositeConstraint的child,则它的delegate是MASCompositeConstraint,但是最终还是会之中maker中的delegate方法。而MASCompositeConstraint的MASConstraintDelegate是maker。注意这个类提供的语法糖,用于方便地进行一组约束的操作,例如edges/size/center等属性。

6. View+MASAdditions:使用mas_makeConstraints/mas_updateConstraints/mas_remakeConstraints等核心入口方法来设置约束,最常用的的核心是mas_updateConstraints,一般来说,使用这个方法即可。

7. MASViewAttribute:用来封装UIView和它的NSLayoutAttribute属性,简单的hold这些引用。

8. MASLayoutConstraint:简单继承NSLayoutConstraint

9. MASUtilities.h:这个文件有个点需要注意,这里定义了MASBoxValue宏,用来将类似int/CGRect/CGSize等值使用NSValue进行封装,变为NSObject对象,可以使MASConstraint的类似equalTo等函数有一个便捷函数mas_equalTo可以使用,例如maker.left.equalTo(@(100))可以写为 maker.left.mas_equalTo(100)。mas_equalTo实际上是#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))宏。

10. NSArray+MASAdditions:一些辅助方法。

二. 代码阅读

通过下面的代码的执行过程说明一下masorny的执行过程
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [testView mas_updateConstraints:^(MASConstraintMaker *make) {  
  2.      make.top.left.width.height.equalTo(@(100)).priorityHigh();  
  3. }];  

先说block中的内容执行:
1. make.top:
MASConstraintMaker的top方法 -> addConstraintWithLayoutAttribute:方法 -> [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute] ,可以发现最终调用的是MASConstraintMaker的MASConstraintDelegate的constraint:addConstraintWithLayoutAttribute:方法,在这个方法的实现内,生成了MASViewConstraint对象作为返回值。可以说这个方法是链式调用的核心方法,由于constraint为nil,所以这里执行的代码很简单。注意这里的把newConstarint的MASConstraintDelegate设置为self,也就是说新生成的MASViewConstraint的delegate是MASViewConstraint。所以make.top的返回值是MASViewConstraint类。
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  2.     MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];  
  3.     MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];  
  4.       
  5.     ….  
  6.   
  7.     if (!constraint) {  
  8.         newConstraint.delegate = self;  
  9.         [self.constraints addObject:newConstraint];  
  10.     }  
  11.     return newConstraint;  
  12. }  

2. make.top.left:
这里的left执行的是MASViewConstraint的left方法,接着调用MASViewConstraint的addConstraintWithLayoutAttribute:方法:
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)left {  
  2.     return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];  
  3. }  

注意,这里的返回值,不是self,而是addConstraintWithLayoutAttribute方法的返回值。而MASViewConstraint的这个方法的实现如下:
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  2.     NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation");  
  3.   
  4.     return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];  
  5. }  

之前我们知道这个MASViewConstraint的delegate就是MASConstraintMaker,所以会再次执行
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {  
  2.     NSUInteger index = [self.constraints indexOfObject:constraint];  
  3.     NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);  
  4.     [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];  
  5. }  
  6.   
  7. - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  8.     MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];  
  9.     MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];  
  10.     if ([constraint isKindOfClass:MASViewConstraint.class]) {  
  11.         //replace with composite constraint  
  12.         NSArray *children = @[constraint, newConstraint];  
  13.         MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];  
  14.         compositeConstraint.delegate = self;  
  15.         [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint];  
  16.         return compositeConstraint;  
  17.     }  
  18.     if (!constraint) {  
  19.         newConstraint.delegate = self;  
  20.         [self.constraints addObject:newConstraint];  
  21.     }  
  22.     return newConstraint;  
  23. }  

由于constraint参数为MASViewConstraint类,这里我们可以看出来,最终的返回值不再是MASViewConstraint,而变成了MASCompositeConstraint类,这个类不仅仅包含left约束(MASViewConstraint),同时也会把top约束(MASViewConstraint)也加入进去,同时会把maker中的constraints数组中top约束(MASViewConstraint)删掉,替换为刚刚生成的MASCompositeConstraint对象。注意,在MASCompositeConstraint对象的initWithChildren方法中,会把所有的child的delegate设置为MASCompositeConstraint对象,而MASCompositeConstraint的delegate则会变成maker。
所以,我们可以看出,make.top.left的返回值是一个MASCompositeConstraint对象,里面包含了top和left约束对象(MASViewConstraint)。

3. make.top.left.width:
这里的width是执行MASCompositeConstraint对象的width方法,接着调用MASCompositeConstraint的addConstraintWithLayoutAttribute:方法
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  2.     [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute];  
  3.     return self;  
  4. }  

这里一定要注意,跟MASViewConstraint和MASConstraintMaker的addConstriantWithLayoutAttribute方法不一样,这里的返回值,不是新生成的MASConstraint对象,而是self,也就是还是这个MASCompositeConstraint对象。这个类调用的是MASCompositeConstraint的方法:
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  2.     id<MASConstraintDelegate> strongDelegate = self.delegate;  
  3.     MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];  
  4.     newConstraint.delegate = self;  
  5.     [self.childConstraints addObject:newConstraint];  
  6.     return newConstraint;  
  7. }  

在这个方法中,最终还是会调用delegate的方法,也就是MASConstraintMaker的方法,上面我们可以看到在MASConstraintMaker的这个方法中,只执行了一部分代码:
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  2.     MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];  
  3.     MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];  
  4.   
  5.     ...  
  6.       
  7.     return newConstraint;  
  8. }  

所以在maker中仅仅是生成MASViewConstraint而已,最终这个对象会被加入到MASCompositeConstraint的child中,并且这个MASViewConstraint的delegate会被设置为MASCompositeConstraint。
所以make.top.left.width执行返回的仍然是make.top.left时生成的MASCompositeConstraint对象,只是会为width生成一个MASViewConstraint约束,并且加入到MASCompositeConstraint对象的child中,并不会把这个约束加入到maker的constraints数组中。

至于,make.top.left.width.height是跟这个一样的执行步骤,不再赘诉。

4. 至于equalTo的调用过程,是使用OC的Dot notation语法,使用这个语法可以直接调用无参数的方法。然后直接使用返回的block进行调用,实现了对约束的设置。

5. mas_updateConstraints方法中,上述block中的内容执行完之后,会调用maker的install方法,这个方法中,会遍历maker中constraints数组,然后调用MASConstraint的install方法。而MASCompositeConstraint对象的install方法会直接调用其child的install方法,并不会额外进行其他操作。所以最终的核心操作是MASViewConstraint的install方法,这个方法中,会生成NSLayoutConstraint约束,然后添加到对应的view中。这个地方其实比较简单,看代码即可。

三. 注意点

1. 通过链式调用可以设置多个属性,比如maker.left.right.top等,这些方法会返回一个MASCompositeConstraint对象,代表left/right/top这些约束的所有MASViewConstraint对象都会被添加到MASCompositeConstraint之中,通过这种方式实现链式调用,可以大大减少代码量。同时通过maker提供的center/edges/size函数也返回MASCompositeConstraint对象,里面同时包含了MASViewConstraint对象,也可以实现同时设置多个属性。注意MASCompositeConstraint源文件中的这段代码,注意这里返回的不是新生成的MASViewConstraint对象:
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {  
  2.      [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute];  
  3.      return self;  
  4. }  


四. 代码阅读心得

1. 使用NSException来解决OC中没有虚函数语法的问题,如果子类未实现虚方法,则直接抛出异常;在iOS中,我们对异常的使用远远不足,思路太过局限于C的思路,比如说出错之后,往往使用返回-1这种方式解决,这点在处理一些比较突出的异常时就非常不够用。例如,在JSON解析的时候对应的数据不对的问题,这个问题再跟服务器约定之后,一般不会出问题,但是一旦遇到问题就对客户端的用于体验造成非常不好的影响,现在的思路是可以使用@try{}@catch来解决,后面会在这方面做一些尝试。

2. 大量使用NSAssert断言工具来调试代码,我自己这方面之前更加喜欢使用if来避免进行各种容错,虽然这种方式,可以避免crash等严重问题,但是开发过程中,会降低开发效率。

3. 对block的灵活使用,这部分也是我最近思考比较多的地方,之前我对block的使用也觉得较多,但是现在看来,使用深度和灵活度都不够,一方面用来替代delegate做回调,这种方式非常灵活便捷,并且逻辑清晰。但是看masonry中的时候,才发现使用block做返回做参数,可以把写代码的过程变得简洁很多,在masonry中,equalTo这些方法的实现就是最好的例子。

4. 类似MASConstraint+Private.h的方式使用category实现类似protected的内部方法继承,这个也比较有意思,也是我之前一个挺困扰的问题,在写类库的时候,可以避免公开接口混乱以及过大的问题,从而很好地划分公开以及内部方法。

5. 类库的封装,调用时要足够简单便捷,通过隐藏大量的内部实现细节,只暴露必要的部分,这样第三方使用者使用起来才不会产生困惑。这部分我自己做的不足,很多时候写代码和类库的时候,写的过于冗余和啰嗦,这也可能是OC没有命名空间带来的习惯影响,后续转向swift之后肯定会大大改善这些问题。

6. Dot Notation语法的使用,也是masonry可以实现链式调用的基础语法,使用dot notation调用方法( 无参数方法)。结合block做返回变量来进行使用,就可以把代码变得非常简单,这种方式就实现所谓的函数式编程。注意,为了更好地维护代码规范,dot notation调用无参数方法这个语法要慎用,一般来说,方法调用就要使用”[]"语法,只有变量使用 “.”,可以避免混乱,增加代码的可阅读性。参考: http://stackoverflow.com/questions/2375943/objective-c-dot-notation-with-class-methods, http://underscorem.org,还有就是参考MASViewConstraint的equalTo等方法的实现代码
照着Masonry敲了遍代码 没事跟着Masonry源代码敲了一遍。收货不小。 立即下载

相关推荐

Masonry(iPhone源代码)

来源:github/MasonryLicence:MIT作者:Masonry Team     Masonry 能够让开发者十分容易使用iOS的自动布局(AutoLayout)机制。Masonry提供更加完善、友好的API来代替直接使用NSLayoutConstraint进行编程,能够使视图布局的过程更加轻松。     例如,需要让某个子视图位于某个父视图的中间,并且子视图上下左右四边离父视图的间距为10px。直接利用NSLayoutConstraint进行编程需要几十行代码,而利用Masonry,代码数量减少了起码三分之二。具体代码看下面的使用方法。

[iOS开发]Masonry源码学习

苹果提供的自动布局(Auto Layout)能够对视图进行灵活有效的布局。但是,使用原生的自动布局相关的语法创建约束的过程是非常冗长的,可读性也比较差。使用原生的自动布局语法,对于如此简单的一个布局,也是非常冗长的。如果使用 VFL(Visual Format Language)可以有效减少冗余,但是其 ASCII 类型语法使得编译器无法做类型检查,存在一定的安全隐患。Masonry 的目标其实就是为了解决原生自动布局语法冗长的问题。

weixin_52192405的博客 551

MasonryDemo:MasonryDemo和Masonry原始解析-源码解析

砌体演示 ## MasonryDemo和Masonry原始解析##类图

【iOS】—— Masonry源码学习(浅看,未完)

Masonry在我们之前的学习中是一个非常有用的第三方库。Masonry是一种基于Objective-C语言的轻量级布局框架,它可以简化iOS应用程序中的自动布局任务。Masonry提供了一个方便的API,可以编写更加简洁和易于阅读的代码来创建约束。使用Masonry,您可以通过链式调用方法来设置视图之间的约束关系,而无需直接操作NSLayoutConstraint对象。简单来说,Masonry就是封装了。在学习源码之前,我们先来看看。

m0_62386635的博客 1270

f2fs学习笔记 - 3. F2FS文件系统布局

目录1.前言2.F2FS布局说明2.1. super block(block 0x0 ~ block 0x1ff)2.2 CP(block 0x200 ~ block 0x5ff)cp page1nat journalsit journaldata summarycurrent hot node summarycurrent warm node summarycurrent cold node summarycp page22nd checkpoint2.3 SIT(block 0x600 ~ block

HZero 4644

硬件-电源-智能保护:eFuse选型与实战设计全攻略

本文深入解析eFuse在硬件电源设计中的关键作用与实战选型技巧。作为智能保护器件,eFuse能提供毫安级精度的过流保护、多重故障防护和智能恢复功能,比传统保险丝快1000倍以上。文章详细介绍了eFuse的工作原理、五大选型维度和PCB布局要点,帮助工程师有效预防电源异常导致的硬件损坏,适用于AI服务器、工业控制等场景。

weixin_30879169的博客 200

Assertion failure in -[MASViewConstraint addConstraintWithLayoutAttribute:],'Attributes should be ch

Assertion failure in -[MASViewConstraint addConstraintWithLayoutAttribute:]。Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attributes should be chained before defining the constraint relation'。libc++abi.dylib: termin

mgr406176009的专栏 2455

【电力系统】高压直流输电VSC-HVDC,四个变流站联合输电 / 交直流混合并网系统

本文研究了一种基于电压源型换流器(VSC)的高压直流输电(HVDC)系统,该系统通过四个变流站实现联合输电并接入交直流混合电网。文章介绍了系统的结构、工作原理以及控制策略,分析了交直流混合并网的特性,并通过仿真验证了系统的性能。结果表明,该系统具有良好的稳定性和灵活性,能够有效实现多点供电和功率协调。

2401_84610415的博客 2239

Masonry的使用(一)--初步使用

Masonry 就是一个第三方为我们封装好的一个框架,其使用点语法,可以非常便利的添加约束,且语法通俗 使用前的准备工作 要在工程中倒入这个第三方库 在工程中创建一个Podfile文件,在位于工程目录的终端窗口中 $ touch Podfile 打开这个文件 写入 platform :ios, '8.0' target ‘MasoryTest’ do pod 'Masonry' ...

鳞潜羽翔 384

Android Qcom USB Driver学习(十三)

该系列文章总目录链接与各部分简介: Android Qcom USB Driver学习(零) Android Qcom USB Driver学习(八) Android Qcom USB Driver学习(九)deals with the USB Power Delivery resources used by one or more ports on the basis of the local device policy the basis of the local device policy.opera

Android驱动开发 2611

【AI 编程工具进阶用法】如何在Cursor、Trae等工具中使用Skills

OpenSkills是一个开源项目,用于在Cursor、Trae等AI编程工具中添加可复用、可组合的"能力模块"。安装流程包括:1)全局安装OpenSkills CLI工具;2)选择安装Anthropic官方Skills到项目或全局;3)创建AGENTS.md文件同步Skills;4)在AI工具中调用Skills。此外还介绍了UI/UX Pro Max Skill项目,通过npm安装后可为AI添加设计能力。这些Skills相当于为AI工具安装"高级技能包"

肌肉金轮的博客 3540

masonry更新xib约束探索

一个有趣的实验 首先做个简单的小实验,在storyboard拖放一个view,添加好约束。之后利用masonry分别去更新这个视图的位置,尺寸。会发现不一样的结果。 //更新尺寸 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ [super touchesBegan:tou...

qq_17190231的博客 1442

海康工业相机使用:常见问题及解决方法

工业相机在使用过程中,经常会因为操作不当、使用环境不当等原因出现一些问题,本篇教程,主要针对海康工业相机常见问题及其定位方法做以简单介绍,希望可以帮助大家。 注:该教程对其他品牌工业相机“常见问题”排查,也具备一定的指导意义。 当出现无法通过客户端发现设备或者无法预览图像等问题,先确认当前的运行环境是否满足以下要求: 确认装有相机驱动软件的电脑网卡为千兆网卡(Gige接口相机); 确认网卡是否已开启巨型帧; 确认电脑与网口相机之间的网络链路为千兆; 确认装有相机驱动软件的USB接口为3...

Cche的博客 3万+

LLDebugTool 项目安装与配置指南

LLDebugTool 项目安装与配置指南 1. 项目基础介绍 LLDebugTool 是一款面向开发者和测试人员的调试工具,它可以帮助你在非 Xcode 环境下分析和操纵数据。该工具适用于那些需要监控网络请求、查看日志信息,但又不想在 Xcode 中运行项目的场景。 主要编程语言:Objective-C 和 Swift 2. 项目使用的关键技术和框架 SQLite:通过 FMDB 这个 Obj...

gitblog_00259的博客 754

【STM32学习】(29)STM32实现595驱动三个数码管(标准库和HAL库实现)

我选用的单片机型号为:STM32F103系列 74LS595是一个串转并行输出的芯片,它能为单片机节省很多的IO口,应用场景广泛。 现要求三个数码管动态显示,常规设计都是并行实现,需要8个IO数据口,然后还需要3个IO片选数码管接口,这样大大占用了IO口,导致连接的外设变少。因此我们引入74LS595芯片。电路设计如下: 只需要三个共阴极数码管与三个595芯片级联即可完成,通过RCLK,SCK,SER三个IO即可完成对数码管的动态控制并显示。电路焊接的实物图如下: 要求完成功能:实现数.

XiaoCaiDaYong的博客 8263

一个服务如何被找到、被调用、被看见:注册中心、发布注册、发现调用与服务监控的治理闭环

服务数量一多,“对方在哪儿”就成了时刻变化的变量。本文沿发布、注册、发现、调用、监控的治理闭环展开:注册中心的数据模型、健康检查与AP/CP取舍,自我保护、推空保护与本地快照三道自保机制;服务发布的启动器、动态代理、发布管理器、协议服务器与登记顺序;消费端的服务目录、请求ID配对、六种集群容错与三种发现模式;日志、指标、链路三支柱与熔断舱壁。配套五个Java演示程序实测:默认参数下宕机实例平均240秒才被摘除,优雅下线可降至45秒,统计窗口长于租约会让自我保护失效,尾部采样可捕获全部慢请求。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 169万+

Masonry源码

这篇文章是 Masonry 框架源码的解析和笔记。学习Masonry之前,先了解这个框架设计的初衷—传统的利用系统API进行纯代码布局的不足。然后,根据Masonry常见的几个链式语法中,顺藤摸瓜地了解Masonry的调用栈。最后,学习并思考这个框架用到的设计模式和链式编程思想。

weixin_61196797的博客 1301

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Masonry与UITableView+FDTemplateLayoutCell搭配使用

Masonry是一款轻量级的布局框架,上手简单。本文只是对此的基本使用,具体可看以下两篇技术博客: iOS 源代码分析----Masonry:http://draveness.me/ios-yuan-dai-ma-fen-xi-masonry/ Masonry介绍与使用实践(快速上手Autolayout):http://adad184.com/2014/09/28/use-masonr

风雪寒晨的博客 1409

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Masonry mas_makeConstraints mas_updateConstraints mas_remakeConstraints 代码详解

自动布局第三方库masonry,让我们能够用链式表达式的方式,优雅地写出自动布局的代码。 masonry 给我们便利的同时,使用过程中又给了我们一些困扰。有的时候布局不正确,却不知道是什么原因。纠结好久发现用错了方法。 到底何时用make, update,remake.今天我就结合源代码,来说说我的理解。个人想法仅供参考。 我们经常用到的有以下三种方法,我们通过源代码及结合实际情况,进行对比,分析...

fiona_yang123456的专栏 1812

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

iOS框架·Masonry源码深度解析及学习启示:设计模式与链式编程思想

传送门:链式编程小Demo 这篇文章是 Masonry 框架源码的解析和笔记。学习Masonry之前,先了解这个框架设计的初衷---传统的利用系统API进行纯代码布局的不足。然后,根据Masonry常见的几个链式语法中,顺藤摸瓜地了解Masonry的调用栈。最后,学习并思考这个框架用到的设计模式和链式编程思想。 1. 之前的不足:系统API纯代码布局 系统给的自动布局(AutoLayout)...

weixin_33873846的博客 345

MasonryDemo:优雅的AutoLayout实现利器

MasonryDemo:优雅的AutoLayout实现利器 1、项目介绍 MasonryDemo 是一个精心编写的开源项目,旨在帮助开发者深入理解和掌握Masonry这一强大的iOS AutoLayout库。通过一系列示例和教程,这个项目提供了一种学习Masonry不同用法的系统性方法,包括基础设置、动态更新、复杂的视图布局等。作者 Huang Yibiao 分享了他的经验,使得每一个源代码都能对...

gitblog_00019的博客 434
上一篇: CocoaPods之----制作
下一篇: ios调打电话代码
Guide_Sun
博客等级 码龄12年 3粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值