iOS小经验·Masonry布局时因不熟悉Cell生命周期而导致死循环

本文属 iOS小经验系列:累积平时看起来简单,容易忽视的边边角角,各路大佬敬请回避。

设置UICollectionView的footer的时候,可能有新的小伙伴这样写:

问题代码:

  • 头文件
#import <UIKit/UIKit.h>

@interface DownloadCollectionFooter : UICollectionReusableView

/** 标题 */
@property (nonatomic,strong) UIButton * footerBtn;
/** 内存 */
@property (nonatomic,strong) NSString * footerStr;

@end
  • 实现文件
#import "DownloadCollectionFooter.h"
#import "Masonry.h"
@implementation DownloadCollectionFooter

- (instancetype)init
{
    self = [super init];
    if (self) {
         //...
    }
    return self;
}

- (void)layoutSubviews{
    
    [super layoutSubviews];
    _footerBtn = [[UIButton alloc]init];
    [_footerBtn setTitle:@"下载" forState:UIControlStateNormal];
    _footerBtn.titleLabel.font = [UIFont systemFontOfSize:15];
    [self addSubview:_footerBtn];
    
    [_footerBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.mas_left).offset(25);
        make.right.equalTo(self.mas_right).offset(-25);
        make.top.equalTo(self.mas_top).offset(7);
        make.height.mas_equalTo(@36);
    }];
}

问题描述

导致死循环地执行layoutSubviews代码。

问题原因

这是因为,通过Masonry设置约束之前的那个addSubview,会导致layoutSubviews再次执行。那么,如果你在layoutSubviews中设置addSubview,就导致死循环了。

解决方案

  • 在初始化的时候设置Masonry。例如下面初始化的时候调用自定义的initSubViews,然后把原来写在layoutSubviews的问题代码写在initSubViews中去。
-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self initSubViews];
    }
    return self;
}

如果你坚持想在layoutSubviews写布局代码,仍然可以,也有个方案:

  • 把addSubview写在初始化方法里面,或者写在子控件的懒加载里面,然后在layoutSubviews的方法里面再用Masonry设置布局约束。
  • 或者,改用frame和bounds等绝对布局方式,addSubview之后,再用绝对布局,并不会导致layoutSubviews再次执行,例如。
- (void)layoutSubviews{
    
    [super layoutSubviews];
    
    _titleLabel = [[UILabel alloc]init];
    [self addSubview:_titleLabel];
    _titleLabel.frame = CGRectMake(0, 7, SCREEN_WIDTH, 24);
    _titleLabel.centerX = self.centerX;
    _titleLabel.text = @"缓存";
    //等等
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏瓜大三哥

优化策略之Opt_design

opt_design [-retarget] [-propconst] [-sweep] [-bram_power_opt] [-remap]

32860
来自专栏用户2442861的专栏

Python-OpenCV 处理图像(二):滤镜和图像运算

喜欢自拍的人肯定都知道滤镜了,下面代码尝试使用一些简单的滤镜,包括图片的平滑处理、灰度化、二值化等:

24410
来自专栏linux驱动个人学习

高通Audio中ASOC的machine驱动

ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的...

1.4K40
来自专栏Android点滴积累

Android高效内存2:让图片占用尽可能少的内存

Android高效内存:让图片占用尽可能少的内存 一、让你的图片最小化 1.1 大图小图内存使用情况对比 大图:440 * 336    小图:220 * 16...

315110
来自专栏小特工作室

基于iTextSharp的PDF文档操作

  公司是跨境电商,需要和各种物流打交道,需要把东西交给物流,让他们发到世界各地。其中需要物流公司提供一个运单号,来追踪货物到达哪里?!   最近在和DHL物流...

283100
来自专栏DannyHoo的专栏

iOS开发中简单代码实现UITableView头视图拉伸效果

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

29230
来自专栏深度学习思考者

关于图像的二维卷积各种版本的实现(C++,Cuda和mex)

  卷积的相关知识本文不再描述,网上大把的资源,本文给出二维卷积的各种版本的实现。 C++版本   首先是最常用的C++版本的卷积实现,代码如下: voi...

324100
来自专栏Python数据科学

快速入门Matplotlib教程

Matplotlib 可能是 Python 2D-绘图领域使用最广泛的套件。它能让使用者很轻松地将数据图形化,并且提供多样化的输出格式。这里将会探索 matpl...

12410
来自专栏落影的专栏

OpenGL ES实践教程(三)镜子效果

教程 OpenGLES实践教程1-Demo01-AVPlayer OpenGL ES实践教程2-Demo02-摄像头采集数据和渲染 其他教程请移步OpenG...

40940
来自专栏向治洪

iOS自动布局框架之Masonry

目前iOS开发中大多数页面都已经开始使用Interface Builder的方式进行UI开发了,但是在一些变化比较复杂的页面,还是需要通过代码来进行UI开发的。...

21860

扫码关注云+社区

领取腾讯云代金券