<article>
每個App的搜索界面下邊都會有熱門搜索,歷史搜索之類的標簽,這里介紹個框架,
既可以非常容易實現標簽類的不規則流式布局,也可以實現固定寬度和高度的布局,也
支持Autolayout,使用起來也是非常舒服。SKTagView原框架下只有根據文字寬度不固
定的的模式,那么如果需求有固定寬高模式的[圖片上傳失敗...(image-21f1d6-1523326930882)]
,老規矩,只能改源碼了.
請看圖:
[圖片上傳失敗...(image-2cb030-1523326930882)]
[圖片上傳失敗...(image-fb582c-1523326930882)]
[圖片上傳失敗...(image-b6d96f-1523326930882)]
傳統模式:
[圖片上傳失敗...(image-af9122-1523326930882)]
TableView cell模式的不規則模式和固定寬高模式:[圖片上傳失敗...(image-1147c4-1523326930882)]
[圖片上傳失敗...(image-9b1050-1523326930882)]
[圖片上傳失敗...(image-af421a-1523326930882)]
[圖片上傳失敗...(image-926856-1523326930882)]
電影放完了,開始簡單介紹下
這里有兩個能用到的地方(截圖來自淘寶)
**[圖片上傳失敗...(image-110276-1523326930876)]
[圖片上傳失敗...(image-c0cfc6-1523326930876)]**
OK,根據以上兩個用途,寫了兩個簡單的Demo,無需再繁瑣的計算了,直接導入
SKTagView來進行布局,非常簡單
Demo地址:https://github.com/DeftMKJ/SKTag
Demo1
首先:
創建一個UISearchBar來進行模擬搜索
[objc] view plain copy
<embed id="ZeroClipboardMovie_1" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_1" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
- (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 44)];
- titleView.backgroundColor = [UIColor clearColor];
- self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 360, 44)];
- self.searchBar.delegate = self;
- self.searchBar.placeholder = @"請輸入要搜索的文字";
- // self.searchBar.showsCancelButton = YES;
- // 鍵盤確認按鈕的名字
- self.searchBar.returnKeyType = UIReturnKeyNext;
- // 把默認灰色背景浮層給去掉
- self.searchBar.backgroundColor = [UIColor clearColor];
- self.searchBar.backgroundImage = [UIImage new];
- UITextField *searBarTextField = [self.searchBar valueForKey:@"_searchField"];
- if (searBarTextField)
- {
- [searBarTextField setBackgroundColor:[UIColor colorWithRed:243/255.0 green:243/255.0 blue:243/255.0 alpha:1]];
- searBarTextField.borderStyle = UITextBorderStyleRoundedRect;
- searBarTextField.layer.cornerRadius = 5.0f;
- }
- else
- {
- // 通過顏色畫一個Image出來
- UIImage *image = [UIImage imageWithColor:[UIColor colorWithRed:243/255.0 green:243/255.0 blue:243/255.0 alpha:1] forSize:CGSizeMake(28, 28)];
- [self.searchBar setSearchFieldBackgroundImage:image forState:UIControlStateNormal];
- }
- [titleView addSubview:self.searchBar];
- self.navigationItem.titleView = titleView;
- [self.searchBar becomeFirstResponder];
- [self configTagView];
- }
來看看效果哈
[圖片上傳失敗...(image-c7d32b-1523326930881)]
但是你們有沒有覺得他右邊的Cancel一點都協調么,要改了它,但是這東西
系統又沒有給屬性接口讓你改......
[圖片上傳失敗...(image-510a7d-1523326930885)]
[圖片上傳失敗...(image-31416c-1523326930885)]
那么試著咱們把SearchBar下面的Subviews統統打印出來看一下
[圖片上傳失敗...(image-dcdd34-1523326930875)]
咦???這個數組里面只有個UIView么,不科學啊,要不再撥開一層看看[圖片上傳失敗...(image-408763-1523326930872)]
[圖片上傳失敗...(image-6f424-1523326930875)]
**[圖片上傳失敗...(image-8279f8-1523326930872)]
NICE啊,這波操作可以啊,找到了,藏那么里面,既然找到了,就在這個代理方法里面進行修改**
[objc] view plain copy
<embed id="ZeroClipboardMovie_2" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_2" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
// (lldb) po self.searchBar.subviews[0].subviews
// <__NSArrayM 0x7ffba1e08330>(
// <UISearchBarBackground: 0x7ffba1c670e0; frame = (0 0; 360 44); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7ffba1c201a0>>,
// <UISearchBarTextField: 0x7ffba1c905b0; frame = (0 0; 0 0); text = ''; clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x7ffba1c90360>>,
// <UINavigationButton: 0x7ffba1c982c0; frame = (0 0; 53 30); opaque = NO; layer = <CALayer: 0x7ffba1c98800>>
// )
//
// (lldb) po self.searchBar.subviews
// <__NSArrayM 0x7ffba1e77280>(
// <UIView: 0x7ffba1c8a470; frame = (0 0; 360 44); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7ffba1c7ddc0>>
// )
searchBar.showsCancelButton = YES;
for(UIView *view in [[[searchBar subviews] objectAtIndex:0] subviews]) {
if([view isKindOfClass:[NSClassFromString(@"UINavigationButton") class]]) {
UIButton * cancel =(UIButton *)view;
[cancel setTitle:@"搜索" forState:UIControlStateNormal];
cancel.titleLabel.font = [UIFont systemFontOfSize:14];
cancel.tintColor = [UIColor redColor];
}
}}
**修改完后的效果(Mac這截圖效果也是醉了[圖片上傳失敗...(image-638db2-1523326930871)]
)**
[圖片上傳失敗...(image-9d3fd1-1523326930884)]
然后
我們來創建SKTagView,各種屬性已經加上注釋
[objc] view plain copy
<embed id="ZeroClipboardMovie_3" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_3" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
// 配置
- (void)configTagView
{
self.label = [[UILabel alloc] initWithFrame:CGRectMake(10, 90, 100, 30)];
self.label.textColor = [UIColor blackColor];
self.label.font = [UIFont systemFontOfSize:13];
self.label.text = @"歷史搜索";
[self.view addSubview:self.label];
// 先移除掉所有
[self.tagView removeAllTags];
// 初始化
self.tagView = [[SKTagView alloc] init];
// 整個tagView對應其SuperView的上左下右距離
self.tagView.padding = UIEdgeInsetsMake(10, 10, 10, 10);
// 上下行之間的距離
self.tagView.lineSpacing = 10;
// item之間的距離
self.tagView.interitemSpacing = 20;
// 最大寬度
self.tagView.preferredMaxLayoutWidth = 375;
// @property (assign, nonatomic) CGFloat regularWidth; //!< 固定寬度
// @property (nonatomic,assign ) CGFloat regularHeight; //!< 固定高度
// 原作者沒有能加固定寬度的,自己修改源碼加上了固定寬度和高度,默認是0,就是標簽式布局,如果實現了,那么就是固定寬度高度
// self.tagView.regularWidth = 100;
// self.tagView.regularHeight = 30;
// 開始加載
[self.dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOLBOOL * _Nonnull stop) {
// 初始化標簽
SKTag *tag = [[SKTag alloc] initWithText:self.dataSource[idx]];
// 標簽相對于自己容器的上左下右的距離
tag.padding = UIEdgeInsetsMake(3, 15, 3, 15);
// 弧度
tag.cornerRadius = 3.0f;
// 字體
tag.font = [UIFont boldSystemFontOfSize:12];
// 邊框寬度
tag.borderWidth = 0;
// 背景
tag.bgColor = [UIColor colorWithRed:244/255.0 green:244/255.0 blue:244/255.0 alpha:1];
// 邊框顏色
tag.borderColor = [UIColor colorWithRed:191/255.0 green:191/255.0 blue:191/255.0 alpha:1];
// 字體顏色
tag.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:53/255.0 alpha:1];
// 是否可點擊
tag.enable = YES;
// 加入到tagView
[self.tagView addTag:tag];
}];
// 點擊事件回調
self.tagView.didTapTagAtIndex = ^(NSUInteger idx){
NSLog(@"點擊了第%ld個",idx);
};
// 獲取剛才加入所有tag之后的內在高度
CGFloat tagHeight = self.tagView.intrinsicContentSize.height;
NSLog(@"高度%lf",tagHeight);
// 根據已經得到的內在高度給SKTagView創建frame
self.tagView.frame = CGRectMake(0, 120, 375, tagHeight);
[self.tagView layoutSubviews];
[self.view addSubview:self.tagView];
}
最后
在UISearchBar的代理方法里面實現搜索的時候隱藏,不搜索的時候顯示
[objc] view plain copy
<embed id="ZeroClipboardMovie_4" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_4" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
- {
- NSLog(@"%@",searchText);
- if (searchText.length == 0) {
- // 沒有文字了
- self.label.hidden = NO;
- self.tagView.hidden = NO;
- }
- else
- {
- self.label.hidden = YES;
- self.tagView.hidden = YES;
- }
- }
三步做完,一個簡單的Demo就做完了,簡單到爆......
下面咱們來看看如何讓他在TableViewCell里面實現高度自適應的
(需要用到的庫UITableView+FDTemplateLayoutCell--->傳送門)
Demo2
首先
用Xib做一個SKTagView的Cell
[圖片上傳失敗...(image-36df22-1523326930874)]
然后
不需要給SKTagView指定Frame了,約束已經做好,只要實現下面的代碼就好了
[objc] view plain copy
<embed id="ZeroClipboardMovie_5" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_5" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
- (void)configCell:(MKJTagViewTableViewCell *)cell indexpath:(NSIndexPath *)indexpath
{
[cell.tagView removeAllTags];
cell.tagView.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width;
cell.tagView.padding = UIEdgeInsetsMake(20, 20, 20, 20);
cell.tagView.lineSpacing = 20;
cell.tagView.interitemSpacing = 30;
cell.tagView.singleLine = NO;
// 給出兩個字段,如果給的是0,那么就是變化的,如果給的不是0,那么就是固定的
cell.tagView.regularWidth = 80;
cell.tagView.regularHeight = 30;
NSArray *arr = [self.dataSource[indexpath.row] valueForKey:@"first"];
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOLBOOL * _Nonnull stop) {
SKTag *tag = [[SKTag alloc] initWithText:arr[idx]];
tag.font = [UIFont systemFontOfSize:12];
tag.textColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
tag.bgColor =[UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
tag.cornerRadius = 5;
tag.enable = YES;
tag.padding = UIEdgeInsetsMake(5, 10, 5, 10);
[cell.tagView addTag:tag];
}];
cell.tagView.didTapTagAtIndex = ^(NSUInteger index)
{
NSLog(@"點擊了%ld",index);
};
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [tableView fd_heightForCellWithIdentifier:identyfy configuration:^(id cell) {
[self configCell:cell indexpath:indexPath];
}];
}
差不多兩個簡單的Demo就介紹到這里了,再提一點東西,原作者是沒有固定寬度這個屬性的,沒辦法,自己動手豐衣足食了,我改了下源碼,主要加了兩個字段,默認是0,那么出來的效果就是不規則的,寬度隨文字而變化,如果賦值這兩個字段,那么就是固定寬高,上面已經給出了效果圖
[objc] view plain copy
<embed id="ZeroClipboardMovie_6" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_6" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
- @property (assign, nonatomic) CGFloat regularWidth; //!< 固定寬度
- @property (nonatomic,assign ) CGFloat regularHeight; //!< 固定高度
給BOOL屬性進行復賦值
[objc] view plain copy
<embed id="ZeroClipboardMovie_7" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_7" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
@interface SKTagView ()
@property (strong, nonatomic, nullable) NSMutableArray *tags;
@property (assign, nonatomic) BOOL didSetup;
@property (nonatomic,assign) BOOL isIntrinsicWidth; //!<是否寬度固定
@property (nonatomic,assign) BOOL isIntrinsicHeight; //!<是否高度固定
@end
@implementation SKTagView
// 重寫setter給bool賦值
- (void)setRegularWidth:(CGFloat)intrinsicWidth
{
if (_regularWidth != intrinsicWidth) {
_regularWidth = intrinsicWidth;
if (intrinsicWidth == 0) {
self.isIntrinsicWidth = NO;
}
else
{
self.isIntrinsicWidth = YES;
}
}
}
主要在下面這個放里面引入了兩個判斷
CGFloat width1 = self.isIntrinsicWidth?self.regularWidth:size.width;
CGFloat height1 = self.isIntrinsicHeight?self.regularHeight:size.height;
[objc] view plain copy
<embed id="ZeroClipboardMovie_8" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_8" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">
-
pragma mark - Private
- (void)layoutTags {
if (self.didSetup || !self.tags.count) {
return;
}
NSArray *subviews = self.subviews;
UIView *previousView = nil;
CGFloat topPadding = self.padding.top;
CGFloat leftPadding = self.padding.left;
CGFloat rightPadding = self.padding.right;
CGFloat itemSpacing = self.interitemSpacing;
CGFloat lineSpacing = self.lineSpacing;
CGFloat currentX = leftPadding;
if (!self.singleLine && self.preferredMaxLayoutWidth > 0) {
for (UIView *view in subviews) {
CGSize size = view.intrinsicContentSize;
CGFloat width1 = self.isIntrinsicWidth?self.regularWidth:size.width;
CGFloat height1 = self.isIntrinsicHeight?self.regularHeight:size.height;
if (previousView) {
// CGFloat width = size.width;
currentX += itemSpacing;
if (currentX + width1 + rightPadding <= self.preferredMaxLayoutWidth) {
view.frame = CGRectMake(currentX, CGRectGetMinY(previousView.frame), width1, height1);
currentX += width1;
} else {
CGFloat width = MIN(width1, self.preferredMaxLayoutWidth - leftPadding - rightPadding);
view.frame = CGRectMake(leftPadding, CGRectGetMaxY(previousView.frame) + lineSpacing, width, height1);
currentX = leftPadding + width;
}
} else {
CGFloat width = MIN(width1, self.preferredMaxLayoutWidth - leftPadding - rightPadding);
view.frame = CGRectMake(leftPadding, topPadding, width, height1);
currentX += width;
}
previousView = view;
}
} else {
for (UIView *view in subviews) {
CGSize size = view.intrinsicContentSize;
view.frame = CGRectMake(currentX, topPadding, self.isIntrinsicWidth?self.regularWidth:size.width, self.isIntrinsicHeight?self.regularHeight:size.height);
currentX += self.isIntrinsicWidth?self.regularWidth:size.width;
previousView = view;
}
}
self.didSetup = YES;
}
介紹完啦,各位還需要細看的請點擊傳送門跑起來看看,不早啦,各位晚安~~~~~~
OVER~~~~~~[圖片上傳失敗...(image-a1d648-1523326930876)]
</article>
版權聲明:本文為博主原創文章,未經博主允許不得轉載。轉載請Email我....... https://blog.csdn.net/Deft_MKJing/article/details/51722157