本文屬 iOS小經(jīng)驗系列:累積平時看起來簡單,容易忽視的邊邊角角,各路大佬敬請回避。
設(shè)置UICollectionView的footer的時候,可能有新的小伙伴這樣寫:
問題代碼:
- 頭文件
#import <UIKit/UIKit.h>
@interface DownloadCollectionFooter : UICollectionReusableView
/** 標(biāo)題 */
@property (nonatomic,strong) UIButton * footerBtn;
/** 內(nèi)存 */
@property (nonatomic,strong) NSString * footerStr;
@end
- 實現(xiàn)文件
#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);
}];
}
問題描述
導(dǎo)致死循環(huán)地執(zhí)行layoutSubviews代碼。
問題原因
這是因為,通過Masonry設(shè)置約束之前的那個addSubview,會導(dǎo)致layoutSubviews再次執(zhí)行。那么,如果你在layoutSubviews中設(shè)置addSubview,就導(dǎo)致死循環(huán)了。
解決方案
- 在初始化的時候設(shè)置Masonry。例如下面初始化的時候調(diào)用自定義的
initSubViews,然后把原來寫在layoutSubviews的問題代碼寫在initSubViews中去。
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initSubViews];
}
return self;
}
如果你堅持想在layoutSubviews寫布局代碼,仍然可以,也有個方案:
把addSubview寫在初始化方法里面,或者寫在子控件的懶加載里面,然后在layoutSubviews的方法里面再用Masonry設(shè)置布局約束。
或者,改用frame和bounds等絕對布局方式,addSubview之后,再用絕對布局,并不會 導(dǎo)致layoutSubviews再次執(zhí)行,例如。
- (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 = @"緩存";
//等等
}
實驗結(jié)論
layoutSubviews里面進行addSubview操作,且通過 Masonry 設(shè)置布局,就 會 導(dǎo)致死循環(huán)地執(zhí)行layoutSubviews。layoutSubviews里面進行addSubview操作,且通過 絕對布局 設(shè)置布局,并不會 導(dǎo)致死循環(huán)地執(zhí)行layoutSubviews。layoutSubviews里面 不 進行addSubview操作,且通過 Masonry 設(shè)置布局,并不會 導(dǎo)致死循環(huán)地執(zhí)行layoutSubviews。