App搜索頁面經常用到關鍵詞提示,例如手機淘寶的【歷史搜索】,網易云音樂的【熱門搜索】。為了方便使用,筆者寫了一個可以流式布局按鈕的view并封裝。
【文末附運行效果及demo】
思考
需要哪些樣式?
- 按鈕帶圓角,有邊框;
- 按鈕寬度根據標題長度自適應;
- 按鈕之間可以調整間距。
流式布局的核心是什么?
- 核心邏輯:當 當前按鈕寬度在視圖水平方向放得下時就把按鈕添加在當前水平方向,當 當前按鈕寬度在視圖水平方向放不下時就換一行添加。
實現
- 自定義一個view,view上的按鈕根據傳進來的關鍵詞數組循環創建。
- 將上一個按鈕做標記,創建當前按鈕時根據上一個按鈕的位置設置當前按鈕位置。
if (i == 0) {
btn.frame = CGRectMake(self.padding, self.padding, rect.size.width + 15, rect.size.height + 15);
}else {
CGFloat leftWidth = CGRectGetWidth(self.frame) - btnPrev.frame.origin.x - btnPrev.frame.size.width - self.padding * 2;
if (leftWidth > rect.size.width) {
btn.frame = CGRectMake(CGRectGetMaxX(btnPrev.frame) + self.padding, btnPrev.frame.origin.y, rect.size.width + 15, rect.size.height + 15);
}else {
btn.frame = CGRectMake(self.padding, CGRectGetMaxY(btnPrev.frame) + self.padding, rect.size.width + 15, rect.size.height + 15);
}
}
- 利用layer設置按鈕圓角、邊框等樣式。
btn.layer.cornerRadius = 12;
btn.layer.masksToBounds = YES;
btn.layer.borderWidth = 1;
btn.layer.borderColor = self.borderColor.CGColor;
- 標記按鈕,利用
block
(也可以選擇代理)將按鈕作為參數傳出,進行點擊事件操作。
- (void)onBtnClick:(UIButton *)btn {
if (self.clickBlock) {
self.clickBlock(btn);
}
}
注意
- view的高度在創建完最后一個按鈕后才能確定,所以在for循環中別忘了最后設置一下view的高度。
//最后一個按鈕時設置視圖高度
if (i == self.words.count - 1) {
CGRect aRect = self.frame;
aRect.size.height = CGRectGetMaxY(btn.frame) + 10;
self.frame = aRect;
}
- 為了更方面使用,封裝view時可以留出屬性接口方便對其設置。
/* 可單獨設置樣式,不設置則為默認樣式
* words 詞匯數組
* btnColor 按鈕背景色
* titleColor 文字顏色
* borderColor 按鈕邊框顏色
* padding 按鈕間隔
* wordHeight 詞匯高度
* fontSize 字體大小
*/
@property (nonatomic, strong) NSArray *words;
@property (nonatomic, strong) UIColor *btnColor;
@property (nonatomic, strong) UIColor *titleColor;
@property (nonatomic, strong) UIColor *borderColor;
@property (nonatomic, assign) CGFloat padding;
@property (nonatomic, assign) CGFloat wordHeight;
@property (nonatomic, assign) CGFloat fontSize;
- 你也可以在自定義view時的初始化方法中添加好默認設置,如果使用時不想過多設置,可以使用默認效果。
//初始化:默認設置
- (instancetype)init {
if (self = [super init]) {
self.btnColor = [UIColor whiteColor];
self.titleColor = [UIColor blackColor];
self.borderColor = [UIColor lightGrayColor];
self.padding = 10;
self.wordHeight = 25;
self.fontSize = 15;
}
return self;
}
- 在
block
中將button
作為唯一參數即可,標題可以通過button.currentTitle
獲取,拿到button
可以做的事情更多,例如改變選中按鈕的顏色等等。
- (void)onBtnClick:(UIButton *)btn {
if (self.clickBlock) {
self.clickBlock(btn);
}
}
效果
總結
這個效果只要理解了流式布局的核心邏輯,處理起來就很簡單了。最后為了方便使用,封裝時注意一些細節即可。