前言
在iOS開發中,隨著iOS裝置的螢幕尺寸不斷更新,對於控制元件約束的新增極為重要。一些常用控制元件的約束新增在這裡不在贅述,本文主要詳細講解UIScrollView的約束新增。在本文中將以兩種方式進行實現,一種為系統的AutoLayout,另一種為藉助Masonry庫檔案。
首先我們在storyboard或xib檔案中拖入一個ScrollView,為其新增距邊緣均為0的約束,即使其充滿螢幕。
對於ScrollView的使用,我們可知的是需要為其設定兩大重要屬性,一為frame二為contentSize。frame用於確定其座標位置,contentSize用於確定其可滾動的區域。
上一步我們已經為ScrollView確定好了其座標位置即frame,接下來我們設定其可滾動的區域。但ScrollView在storyboard或xib中並不可以設定其contentSize,因此我們繼續拖入一個View作為ScrollView的子檢視,大家可認為此View為ScrollView的contentView,使用其來控制ScrollView的滾動區域
contentView作為ScrollView的子檢視,設定其約束為距ScrollView邊緣為0,約束新增好後發現出現了約束報錯,下步我們加以解決。
在解決約束報錯之前我們需要考慮當前ScrollView的滾動方式
若希望ScrollView橫向滾動,我們勾線如圖Vertically in Container選項,即豎直居中;若希望豎向滾動,我們勾選如圖Horizontally in Container選項;若希望ScrollView橫向豎向均可滾動,則無需勾選任何選項,跳過此部即可。
以橫向滾動為例,高度無須操作,需要限制contentView的寬度,例如將其設定為當前螢幕寬的兩倍
簡單為contentView設定個顏色,執行專案,我們即可發現我們生成了一個可滾動的ScrollView,其frame為(0,0,self.view.bounds.size.width,self.view.bounds.size.height),contentSize為(self.view.bounds.size.width*2,self.view.bounds.size.height)
對於contentSize我們也可以手動設定,可將contentView的寬度約束拖入程式碼進行更改
例如我們在程式碼中重新設定其約束
_widthLayout.constant = [UIScreen mainScreen].bounds.size.width * 5;複製程式碼
當前ScrollView可滾動區域橫向即變成了5倍螢幕的大小。
接下來我們為ScrollView設定子檢視。
為了顯示效果較好,我們設定UIImageView作為ScrollView子檢視,首先放置第一個ImageView,設定約束為左上下邊緣約束均為0。
繼續放置第二個ImageView,這隻約束為上下左右約束均為0
最後我們選中兩個ImageView,設定其等寬等高。
執行當前專案,即可實現如下效果
最後放下層級關係方便大家理解
使用系統的AutoLayout為UIScrollView新增約束就告一段落,在真實的開發中,使用ScrollView通常是製作廣告展示位。而廣告位的圖片個數是動態不固定的,因此通過storyboard或xib無法實現需求中的動態新增。我們通常是For迴圈建立指定數量的圖片(子檢視),這就需要我們通過程式碼手動為子檢視新增約束。
具體實現原理與AutoLayout的約束新增一致,詳細見程式碼,這裡使用Masonry庫檔案新增約束,摘取部分約束程式碼如下:
[_scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(_scrollView);
make.centerY.equalTo(_scrollView.mas_centerY).offset(0);
make.width.equalTo(@(self.bounds.size.width * _imageArr.count));
}];
CGFloat space = 0;
//用於接收上一控制元件
UIImageView *lastImageView;
for (NSInteger i = 0; i < _imageArr.count; i++) {
UIImageView *imageView = [self viewWithTag:1000 + i];
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_contentView.mas_top).offset(space);
make.bottom.equalTo(_contentView.mas_bottom).offset(space);
if (lastImageView) {
//如果存在上一控制元件,設定與上一控制元件右邊緣約束,設定等寬
make.left.equalTo(lastImageView.mas_right).offset(space);
make.width.equalTo(lastImageView.mas_width);
} else {
//不存在上一控制元件,設定與父檢視左邊緣約束,設定寬度為當前檢視寬度
make.left.equalTo(_contentView.mas_left).offset(space);
make.width.equalTo(@(self.bounds.size.width));
}
if (i == _imageArr.count - 1) {
//若為最後一個控制元件,設定與父檢視右邊緣約束
make.right.equalTo(_contentView.mas_right).offset(space);
}
}];
//接收上一控制元件
lastImageView = imageView;
}複製程式碼
呼叫方式如下
SureAutoLayoutScrollView *scrollView = [[SureAutoLayoutScrollView alloc]init];
scrollView.imageArr = @[@"IMG_1018.JPG",@"IMG_0857.JPG",@"IMG_0856.JPG"];
[self.view addSubview:scrollView];
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
}];複製程式碼
具體邏輯已註釋標明,完整程式碼已上傳GitHub
Masonry版:github.com/LSure/SureA…
AutoLayout版:github.com/LSure/SureS…