AutoLayout和Masonry兩種方式實現自動佈局的內容包裹和檢視均分
前言
這兩種方式分別代表了兩種人,一種快速佈局,直觀,但是很多人認為很難維護,後者純程式碼佈局,老一派的人用起來都說好,反正一說起來就打起來了,一個雖然快,但是難以維護啊,一個雖然寫起來很多,但是維護起來簡單啊,巴拉巴拉的,我個人覺得,適配的話最好能深刻理解AutoLayout,Apple特有的東西,理解下也好,有了直觀的理解之後,你再用Masonry就非常的簡單了,個人觀點而已,不喜勿噴,主要之前參與的App有兩個是純AutoLayout,沒錯,是純的,而且是多人開發,玩起來一樣沒問題,現在對這些東西理解的還算可以,報錯什麼的也能及時搞定了,廢話不多了,記錄了兩個最常用的知識點
示例圖
分析
上面兩個圖是程式碼完成,下面兩個是自動佈局,現在簡單看下區別和實現
AutoLayout實現包裹和均分
以下是均分的約束,這裡看不懂的就可以去面壁了,去翻翻我之前的幾篇部落格就知道了,基本上就是紅色新增上,左,下的約束,然後黃色新增上,右,下,左,再來個等寬,搞定
以下是子檢視內容撐開父視(父檢視frame不定)的約束,首先你的灰色底部父檢視我只給定了X和Y的座標,size不定,然後內部黑色填充上,左,下,然後給Size,藍色填充上,右,下,左邊,然後給size
注意:這裡看起來簡單,如果你做內容包裹,你像我這麼做這裡有個坑,其實這個就是反面教材,這裡其實只處理了一種等高的情況,如果你的左邊和右邊高度不一樣,系統會給出你警告,讓你再自己看看這不合理的約束,類似於這種錯誤,其實就是你的約束不是完美的,有衝突了,這個如果你用程式碼寫,你就很難最終和找到了,但是你用Autolayout,你根本不需要Run,在拉約束的時候就看到了,這也算是個優點吧,下面再看看不等高的程式碼實現
2017-05-10 15:15:41.717981+0800 SystemTime[55019:5807911] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600000085a00 UIView:0x7f8bbf70c350.height == 100>",
"<NSLayoutConstraint:0x600000085af0 UIView:0x7f8bbf70c6f0.height == 70>",
"<NSLayoutConstraint:0x600000085b40 UIView:0x7f8bbf70c1b0.bottom == UIView:0x7f8bbf70c6f0.bottom + 10>",
"<NSLayoutConstraint:0x600000085b90 UIView:0x7f8bbf70c6f0.top == UIView:0x7f8bbf70c1b0.top + 10>",
"<NSLayoutConstraint:0x600000085c80 UIView:0x7f8bbf70c350.top == UIView:0x7f8bbf70c1b0.top + 10>",
"<NSLayoutConstraint:0x600000085d20 UIView:0x7f8bbf70c1b0.bottom == UIView:0x7f8bbf70c350.bottom + 10>"
)
Masonry實現包裹和均分
很明顯能看出,上面是均分,下面是包裹,直接看程式碼吧
// 程式碼實現內容包裹和均分
@property (nonatomic,strong) UIView *backView;
// 均分父檢視(父檢視X,Y,W,H都已知,代表frame已定)
@property (nonatomic,strong) UIView *averageView;
@property (nonatomic,strong) UIView *averageLeftView;
@property (nonatomic,strong) UIView *averageRightView;
// 用子檢視的內容來填充賦值父檢視的frame 父檢視已知X,Y,height和width都是由子檢視來填充
@property (nonatomic,strong) UIView *fillBackView;
@property (nonatomic,strong) UIView *fillLeftView;
@property (nonatomic,strong) UIView *fillMiddleView;
@property (nonatomic,strong) UIView *fillRightView;
self.backView = [[UIView alloc] init];
self.backView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.7];
[self.view addSubview:self.backView];
[self.backView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.view);
make.height.equalTo(@([UIScreen mainScreen].bounds.size.height/2.5));
}];
self.averageView = [[UIView alloc] init];
self.averageView.backgroundColor = [UIColor blackColor];
[self.backView addSubview:self.averageView];
[self.averageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.backView);
make.height.equalTo(self.backView.mas_height).multipliedBy(0.5);
}];
self.averageLeftView = [[UIView alloc] init];
self.averageLeftView.backgroundColor = [UIColor blueColor];
[self.averageView addSubview:self.averageLeftView];
[self.averageLeftView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.equalTo(self.averageView).with.offset(10);
make.bottom.equalTo(self.averageView).with.offset(-10);
}];
self.averageRightView = [[UIView alloc] init];
self.averageRightView.backgroundColor = [UIColor greenColor];
[self.averageView addSubview:self.averageRightView];
[self.averageRightView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.bottom.equalTo(self.averageView).with.offset(-10);
make.top.equalTo(self.averageView).with.offset(10);
make.left.equalTo(self.averageLeftView.mas_right).with.offset(10);
make.width.equalTo(self.averageLeftView.mas_width);
}];
self.fillBackView = [[UIView alloc] init];
self.fillBackView.backgroundColor = [UIColor purpleColor];
[self.backView addSubview:self.fillBackView];
// 包裹內容
[self.fillBackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.averageView.mas_bottom).with.offset(30);
make.centerX.equalTo(self.backView);
}];
// 子檢視填充
self.fillLeftView = [[UIView alloc] init];
self.fillLeftView.backgroundColor = [UIColor redColor];
[self.fillBackView addSubview:self.fillLeftView];
[self.fillLeftView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.equalTo(self.fillBackView).with.offset(10);
make.centerY.equalTo(self.fillBackView);
make.left.equalTo(self.fillBackView).with.offset(10);
// make.bottom.equalTo(self.fillBackView).with.offset(-10);
make.size.mas_equalTo(CGSizeMake(80, 60));
}];
self.fillMiddleView = [[UIView alloc] init];
self.fillMiddleView.backgroundColor = [UIColor orangeColor];
[self.fillBackView addSubview:self.fillMiddleView];
[self.fillMiddleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.fillLeftView.mas_right).with.offset(10);
make.centerY.equalTo(self.fillBackView);
// make.top.equalTo(self.fillBackView).with.offset(10);
// make.bottom.equalTo(self.fillBackView).with.offset(-10);
make.size.mas_equalTo(CGSizeMake(30, 60));
}];
self.fillRightView = [[UIView alloc] init];
self.fillRightView.backgroundColor = [UIColor blueColor];
[self.fillBackView addSubview:self.fillRightView];
[self.fillRightView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.bottom.equalTo(self.fillBackView).with.offset(-10);
make.top.equalTo(self.fillBackView).with.offset(10);
make.left.equalTo(self.fillMiddleView.mas_right).with.offset(10);
make.size.mas_equalTo(CGSizeMake(200, 100));
}];
這裡我之前也是和上面的AutoLayout一樣是等高的示例,就是那幾句注掉的程式碼,但是為了突出剛才的約束嚴格意義上來講是有問題的,因此這裡給了一個不等高的特殊情況,程式碼很少,隨意感受下效果,最後的點選事件
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self.fillRightView mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@10);
}];
[self.averageRightView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.averageLeftView.mas_right).with.offset(300);
}];
[UIView animateWithDuration:2.0f animations:^{
[self.fillBackView layoutIfNeeded];
[self.averageView layoutIfNeeded];
self.backView.hidden = YES;
}];
}
Demo地址
Demo裡面還有一個另外的東西,由於都只是小知識點,就放在一起了,一個對iOS設計倒數計時的思路和遇到的坑
cell倒數計時問題遇到的坑
相關文章
- iOS自動佈局——Masonry詳解iOS
- html隨意拖動內容位置的兩種實現方式HTML
- 使用第三方框架 Masonry 實現自動佈局框架
- Masonry佈局控制元件,自動換行控制元件
- css佈局-實現左中右佈局的5種方式CSS
- 三欄式佈局的幾種實現方式
- 水平垂直居中佈局的多種實現方式
- CSS 兩欄佈局和三欄佈局CSS
- 使用 CSS columns 佈局來實現自動分組佈局CSS
- 浮動佈局 和 flex佈局Flex
- 網頁佈局------幾種佈局方式網頁
- vue移動端的自適應佈局的兩種解決方案Vue
- 圓形視訊和圓角視訊的一種實現方式
- wxPython 中的動態內容與佈局管理Python
- CSS進階內容——佈局技巧和細節修飾CSS
- 兩種方式實現橫向滾動條
- 實現動態自動匹配輸入的內容
- 如何實現兩欄佈局,右側自適應?三欄佈局中間自適應呢?
- CSS佈局–聖盃佈局和雙飛翼佈局以及使用Flex實現聖盃佈局CSSFlex
- Spring實現IOC容器的兩種實現方式Spring
- Angular-3種建立動態內容的方式Angular
- Masonry佈局簡單朋友圈
- 基於 Electron 做視訊會議的兩種實現方式
- 頁面佈局的相關內容
- IOS橫線滾動檢視的實現---方式二iOS
- 實現三欄佈局的幾種方法
- 一種子圖佈局方法的實現
- 面試官問:你有多少種方式實現三欄佈局?面試
- flexbox佈局下flex:auto的元素沒有平均分佈Flex
- UITableViewCell使用自動佈局的“最佳實踐”UIView
- 兩種方式實現輪播圖
- SpringBoot實現熱部署兩種方式!Spring Boot熱部署
- 如何使用Flexbox和CSS Grid,實現高效佈局FlexCSS
- 有關石油的各種遊戲:操作方式和內容的不同訴求遊戲
- 前端--實現隔行變色的兩種方式前端
- kivy八種佈局方式學習
- 用Flex實現常見的幾種佈局Flex
- ASP.NET Core 5.0 MVC中的檢視分類——佈局檢視、啟動檢視、具體檢視、分部檢視ASP.NETMVC
- vue專案多路由表頭吸頂實現的幾種佈局方式Vue路由