Masonry-AutoLayout的第一次使用心得

此前我曾有几次专门查阅过 AutoLayout 的相关资料,好吧其实就是一些牛牛在自己的博客发表的使用教程及一些心得😂。一直都想着试一下但是一直没有什么时间来实践,这篇文章主要说的是我是怎样将 Masonry 移植到原有代码中。

如果你的项目中还没有 Masonry,你可以通过第三方管理平台 Cocoapods 来下载,如果有兴趣的话,可以看一下我之前整理的关于 Cocoapods 下载与安装的文章: IOS依赖管理 - CocoaPods.

首先简单介绍一下 Masonry,Masonry 是一款能够让开发者十分容易使用iOS的自动布局(AutoLayout)机制。Masonry提供更加完善、友好的API来代替直接使用NSLayoutConstraint进行编程,能够使视图布局的过程更加轻松。(好吧我承认这句话是我拷贝过来的😂,这不是重点)

而我对 Masonry 最初的认识是通过这篇文章:Masonry介绍与使用实践:快速上手Autolayout -  CocoaChina 苹果开发中文站 - 最热的iPhone开发社区 最热的苹果开发社区 最热的iPad开发社区,并且我发现网络上流传的大部分关于 Masonry 的文章基本都来自于此,所以如果你对 Masonry 一点了解都没有,这篇文章确实是很不错的。

前期都铺垫完了,接下来咱们就看看我是怎样把原来好好的代码改成了 Autolayout 的好好的代码的了😂

这是一个饼图的控件:

之前的代码是这样的:

通过 initWithFrame 初始化控件的时候传进来的 frame 计算饼图的半径,根据计算出来的半径确定各个 view 的摆放位置:

- (id)initWithFrame:(CGRect)frame{

    self = [super initWithFrame:frame];

    if(self){

         self.backgroundColor = [UIColor clearColor];

         //UIScollView 容器

         _scrollContentView = [[UIScrollView alloc] initWithFrame:self.bounds];

         _scrollContentView.backgroundColor = [UIColor clearColor];

         [self addSubview:_scrollContentView];

         //饼图

         _pieView = [[UIView alloc] initWithFrame:self.bounds];

         _pieView.backgroundColor = [UIColor clearColor];

         [_scrollContentView addSubview:_pieView];

         //饼图中心白色信息区域

         _infoView = [[UIView alloc] initWithFrame:self.bounds];

         _infoView.backgroundColor = [UIColor whiteColor];

         [_scrollContentView addSubview:_infoView];

         //颜色说明

         _descriptionView = [[UIView alloc] initWithFrame:self.bounds];

         _descriptionView.backgroundColor = [UIColor clearColor];

         [_scrollContentView addSubview:_descriptionView];


         //计算饼图半径

         self.pieRadius = MIN(self.bounds.size.width/2, self.bounds.size.height/2) - kMarginX*2;

         self.pieCenter = CGPointMake(self.bounds.size.width/2, _pieRadius + kMarginY);

         _animationArr = [NSMutableArray array];

         self.textRadius = _pieRadius - (_pieRadius-kInfoRadius)/2;

         }

    return self;

}


- (void)setPieCenter:(CGPoint)pieCenter{

    [_pieView setCenter:pieCenter];

    [_infoView setCenter:pieCenter];

    //这个点是方便用来在饼图上面画扇叶用的,是以饼图为基准的中心值

    _pieCenter = CGPointMake(_pieView.frame.size.width/2, _pieView.frame.size.height/2);

}

- (void)setPieRadius:(CGFloat)pieRadius{

    _pieRadius = pieRadius;

    CGRect frame = CGRectMake(_pieCenter.x - pieRadius, _pieCenter.y - pieRadius, pieRadius*2, pieRadius*2);

    _pieCenter = CGPointMake(frame.size.width/2,frame.size.height/2);

    //设置饼图 frame

    [_pieView setFrame:frame];

    [_pieView.layer setCornerRadius:_pieRadius];

    CGFloat infoRadius = kInfoRadius;

    frame = CGRectMake(_pieCenter.x - infoRadius, _pieCenter.y - infoRadius, infoRadius*2, infoRadius*2);

    //设置白色信息图 frame

    [_infoView setFrame:frame];

    [_infoView.layer setCornerRadius:infoRadius];

}

从上面的代码,你应该能看出代码原来的逻辑顺序,这样处理代码的目的就是通过在初始化这个控件的时候就根据给定的 frame 宽高取最小值作为饼图的直径,进而确定饼图以及白色信息图的frame,但是前提我刚说了,一切都建立在 frame 是一个给出的固定值的基础上的。我这样说你可能会觉得奇怪,frame 本来就是一个固定好的确切的CGRect 啊什么鬼啊是不是神经啊😂 那么什么情况下你并不知道 frame 到底是多少呢?那就是我在初始化这个控件的时候也用了 AutoLayout,也就是说我在上一个界面就是通过约束来管理这个控件的布局,那么我只需要给定约束条件就好并不需要传一个固定的值来给这个控件,像这样:

WS(weakSelf);

_pie = [[PieChart alloc] initWithFrame:CGRectZero];

_pie.dataSource = self;

[self.view addSubview:_pie];

[_pie mas_makeConstraints:^(MASConstraintMaker *make) {

    make.edges.equalTo(weakSelf.view);

}];

就像你看到的,我在初始化的时候并没有给出一个固定好的有用的 frame,而是加了一句约束条件,这一句话的意思就是 pie 的大小要跟当前的 view 一样大,是的,这一切都是自动的。

那么现在我要做的就是让 pie 里面的部分控件也 autoLayout,但是我还是需要把 view 的 frame 告诉 pie,因为我原本有一个逻辑是需要取frame 宽高最小值来作为饼图的直径的,真恼人,那么我们就应该想办法告诉 pie 我现在的 frame 是多大,你再来做相应调整。好吧,我先来通知 pie:

-(void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];

    _pie.frame = self.view.bounds;

}

那么现在我在 pie 里就需要改了:

- (id)initWithFrame:(CGRect)frame{

    self = [super initWithFrame:frame];

    if(self){

          self.backgroundColor = [UIColor clearColor];

         WS(weakSelf);

         _scrollContentView = [[UIScrollView alloc] initWithFrame:self.bounds];

         _scrollContentView.backgroundColor = [UIColor clearColor];

         [self addSubview:_scrollContentView];

         [_scrollContentView mas_makeConstraints:^(MASConstraintMaker *make) {

              //重点来了,scrollview 要求跟当前 view 一边大

              make.edges.equalTo(weakSelf);

         }];


         __weak UIScrollView *weakScroll = _scrollContentView;

         _pieView = [[UIView alloc] initWithFrame:self.bounds];

         _pieView.backgroundColor = [UIColor clearColor];

         [_scrollContentView addSubview:_pieView];

         [_pieView mas_makeConstraints:^(MASConstraintMaker *make) {

              //饼图中心点 X 值要跟 scrollview 一样,头部要在 scrollview 上留出kMarginY大小的距离

              make.centerX.equalTo(weakScroll.centerX);

              make.top.equalTo(weakScroll.top).with.offset(kMarginY);

         }];


         __weak UIView *weakPie = _pieView;

         _infoView = [[UIView alloc] initWithFrame:self.bounds];

         _infoView.backgroundColor = [UIColor whiteColor];

         [_scrollContentView addSubview:_infoView];

         [_infoView mas_makeConstraints:^(MASConstraintMaker *make) {

              //白色信息图的中心点 X 值 Y 值都要跟饼图一样

              make.centerX.equalTo(weakPie.centerX);

              make.centerY.equalTo(weakPie.centerY);

         }];


         _descriptionView = [[UIView alloc] initWithFrame:self.bounds];

         _descriptionView.backgroundColor = [UIColor clearColor];

         [_scrollContentView addSubview:_descriptionView];

         [_descriptionView mas_makeConstraints:^(MASConstraintMaker *make) {

              //颜色说明 view 的宽度要跟 scrollview 一样,头部要在饼图底部距离kPieDesSpace的位置

              make.width.equalTo(weakScroll);

              make.top.equalTo(weakPie.bottom).with.offset(kPieDesSpace);

         }];

   }

    return self;

}

-(void)setFrame:(CGRect)frame{

    [super setFrame:frame];

    self.pieRadius = MIN(self.bounds.size.width/2, self.bounds.size.height/2) - kMarginX*2;

    _animationArr = [NSMutableArray array];

    self.textRadius = _pieRadius - (_pieRadius-kInfoRadius)/2;

    //注意这里用到的是 update,因为我之前已经对他们设置过约束,我只是想添加新的约束,如果还是用make 的话之前的所有约束都会无效,如果用 remake 的话就是把之前的相应约束替换掉。因为我现在已经知道 frame 了,现在我可以将他们的大小进行约束了

    [_pieView updateConstraints:^(MASConstraintMaker *make) {

         make.size.mas_equalTo(CGSizeMake(_pieRadius*2, _pieRadius*2));

    }];

    [_infoView updateConstraints:^(MASConstraintMaker *make) {

         make.size.mas_equalTo(CGSizeMake(kInfoRadius *2, kInfoRadius *2));

    }];

}

- (void)setPieRadius:(CGFloat)pieRadius{

    _pieRadius = pieRadius;

    [_pieView.layer setCornerRadius:_pieRadius];

    [_infoView.layer setCornerRadius:kInfoRadius];

}

完成。

我已经不想再说什么啦,这个代码为毛只能一行一行的复制粘贴进去啊!并且我的空格怎么都不见了啊!我是手动的敲的这些空格啊!!手都快抽筋了啊啊啊!!!

好吧,其实这个复制粘贴代码这么难用我还是坚持着手动一行一行复制粘贴下来空格敲的这么完美,都是因为我的好朋友在帮我摘我最喜欢吃的樱桃准备给我寄过来!我不禁哼起歌来~一想到这呀~就让我快乐~贴一张图馋馋你们哈哈哈!


图片发自简书App

噢噢太激动了忘记了总结😒

其实一开始用autolayout我是拒绝的,想到要xb、sb还有官方那么繁琐的语句喔喔还有那个看不懂的象形文字😒我就浑身脑袋疼!但是现在有了这么方便的Masonry,就学来用用吧,毕竟苹果的屏幕大小已经开始不一样了,用一个朋友的话来说,autolayout是趋势。不管怎样,了解下总是好的😜

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容