热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

标签流水布局(TagsView)一行显示不下的自动折行

项目中经常遇到很多标签排列的那种, 之前一直用HXTagsView, 但是一个很小的需求, 就动用UICollectionView甚至是第三方, 总觉得有点小题大做, 索性自己动手写一个, 先看下效果

项目中经常遇到很多标签排列的那种, 之前一直用HXTagsView, 但是一个很小的需求, 就动用UICollectionView甚至是第三方, 总觉得有点小题大做, 索性自己动手写一个, 先看下效果图


核心代码:

CGFloat currentX = 10;CGFloat currentY = 44;CGFloat spaceX = 10; // 左右的空隙CGFloat spaceY = 15; // 上下的空隙CGFloat marginRL = 10; // 文字距左右边框的间距CGFloat lineH = 25;for (int i = 0; i kDeviceWidth-20) {currentY += currentX == 10 ? 0:(lineH+spaceY); // 第一行已经有的话折行 否则就显示在第一行currentX = 10;button.frame = CGRectMake(currentX, currentY, kDeviceWidth-20, lineH);currentX = 10; //currentY += lineH+spaceY;}// 剩余的空间 能显示下else if (kDeviceWidth-currentX-25 > width) {button.frame = CGRectMake(currentX, currentY, width, lineH);currentX += width+spaceX;}// 剩余的空间 显示不下 需要折行显示(但是这一行还没显示满 故不更新currentY)else{currentY += lineH+spaceY;currentX = 10;button.frame = CGRectMake(currentX, currentY, width, lineH);currentX += width+spaceX;}[self addSubview:button];}self.frame = CGRectMake(0, 0, kDeviceWidth, currentY+lineH+10);

具体样式可以自己修改,核心还是布局计算那块

完整代码如下:

typedef void(^HistoryBlock)(NSString *keyword, NSInteger index);
@interface SearchHistoryView : UIView
@property (nonatomic, strong) NSMutableArray *keywords; // 只保留最新的十条记录
@property (nonatomic, copy) HistoryBlock handle;/** 保存一条新的搜索记录*/
+ (BOOL)saveKeyword:(NSString *)keyword;
@end
实现:

@implementation SearchHistoryView- (instancetype)init
{self = [super init];if (self) {[self setUpSubviews];}return self;
}- (void)reloadData{for (UIView *view in self.subviews) {[view removeFromSuperview];}[self setUpSubviews];
}- (void)setUpSubviews{UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, kDeviceWidth-20, 44)];titleLabel.font = kNormalFont(14);titleLabel.text = @"最近搜索";titleLabel.textColor = kColor333333;// UIButton *clear = [[UIButton alloc] initWithFrame:CGRectMake(kDeviceWidth-50, 0, 40, 44)];
// clear.hidden = self.keywords.count == 0;
// [clear setImage:Image(@"icon_cache") forState:UIControlStateNormal];
// [clear addTarget:self action:@selector(clearKeywords) forControlEvents:UIControlEventTouchUpInside];
// [self addSubview:clear];[self addSubview:titleLabel];CGFloat currentX = 10;CGFloat currentY = 44;CGFloat spaceX = 10; // 左右的空隙CGFloat spaceY = 15; // 上下的空隙CGFloat marginRL = 10; // 文字距左右边框的间距CGFloat lineH = 25;for (int i = 0; i// button.layer.cornerRadius = 4;
// button.layer.borderColor = kColor999999.CGColor;
// button.layer.borderWidth = 1;[button setTitle:keyword forState:UIControlStateNormal];[button setTitleColor:kColor666666 forState:UIControlStateNormal];[button addTarget:self action:@selector(itemEvent:) forControlEvents:UIControlEventTouchUpInside];// 一行显示不下if (width > kDeviceWidth-20) {currentY += currentX == 10 ? 0:(lineH+spaceY); // 第一行已经有的话折行 否则就显示在第一行currentX = 10;button.frame = CGRectMake(currentX, currentY, kDeviceWidth-20, lineH);currentX = 10; //currentY += lineH+spaceY;}// 剩余的空间 能显示下else if (kDeviceWidth-currentX-25 > width) {button.frame = CGRectMake(currentX, currentY, width, lineH);currentX += width+spaceX;}// 剩余的空间 显示不下 需要折行显示(但是这一行还没显示满 故不更新currentY)else{currentY += lineH+spaceY;currentX = 10;button.frame = CGRectMake(currentX, currentY, width, lineH);currentX += width+spaceX;}[self addSubview:button];}self.frame = CGRectMake(0, 0, kDeviceWidth, currentY+lineH+10);
}#pragma mark - 数据
/** 获取当前关键字*/
- (NSMutableArray *)keywords{NSString *path = [SearchHistoryView getFilePath];_keywords = [NSMutableArray arrayWithContentsOfFile:path];if (_keywords == nil) {_keywords = [NSMutableArray array];}return _keywords;
}/** 保存关键字*/
+ (BOOL)saveKeyword:(NSString *)keyword{if (keyword == nil || keyword.trim.length == 0) return NO;NSString *path = [self getFilePath];NSMutableArray *keywords = [NSMutableArray arrayWithContentsOfFile:path];// 空的if (keywords == nil) {keywords = [NSMutableArray array];}// 已经把包含if ([keywords containsObject:keyword]) {[keywords removeObject:keyword];}[keywords insertObject:keyword atIndex:0];// 超过十个if (keywords.count >10) {[keywords removeLastObject];}return [keywords writeToFile:path atomically:YES];
}#pragma mark - 事件
- (void)itemEvent:(UIButton *)button{if (_handle) {NSInteger index = [self.keywords indexOfObject:button.currentTitle];self.handle(button.currentTitle, index);}if ([SearchHistoryView saveKeyword:button.currentTitle]) {NSLog(@"保存搜索词成功");}[self removeFromSuperview];
}/** 清除所有关键字*/
- (void)clearKeywords{NSString *path = [SearchHistoryView getFilePath];NSMutableArray *keywords = [NSMutableArray arrayWithContentsOfFile:path];[keywords removeAllObjects];[keywords writeToFile:path atomically:YES];[self reloadData];[self removeFromSuperview];
}+ (NSString *)getFilePath{// 获取 document 路径NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];// 获取 document下 文件夹路径NSString *directory = [document stringByAppendingPathComponent:@"AntiFakeChain"];// 判断文件夹是否存在BOOL isDirectory;BOOL isExistDirectory = [[NSFileManager defaultManager] fileExistsAtPath:directory isDirectory:&isDirectory] && isDirectory;// 如果不存在创建文件夹if (isExistDirectory == NO){[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil];}// 获取文件路径NSString *path = [directory stringByAppendingPathComponent:@"SeachHistory.plist"];return path;
}
@end



推荐阅读
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 如何使用 net.sf.extjwnl.data.Word 类及其代码示例详解 ... [详细]
  • 利用C#技术实现Word文档的动态生成与编辑
    本文通过一个简单的示例,介绍了如何使用C#语言实现Word文档的动态生成与编辑功能。文章详细阐述了在项目中引用Word动态库的方法,并通过具体代码示例展示了如何创建和操作Word表格。此内容旨在为初学者提供参考和学习资料,欢迎读者提出宝贵意见和建议。 ... [详细]
  • 本文探讨了如何在C#中实现USB条形码扫描仪的数据读取,并自动过滤掉键盘输入,即使不知道设备的供应商ID(VID)和产品ID(PID)。通过详细的技术指导和代码示例,展示了如何高效地处理条形码数据,确保系统能够准确识别并忽略来自键盘的干扰信号。该方法适用于多种USB条形码扫描仪,无需额外配置设备信息。 ... [详细]
  • 本文将详细介绍在Android应用中添加自定义返回按钮的方法,帮助开发者更好地理解和实现这一功能。通过具体的代码示例和步骤说明,本文旨在为初学者提供清晰的指导,确保他们在开发过程中能够顺利集成返回按钮,提升用户体验。 ... [详细]
  • Android 图像色彩处理技术详解
    本文详细探讨了 Android 平台上的图像色彩处理技术,重点介绍了如何通过模仿美图秀秀的交互方式,利用 SeekBar 实现对图片颜色的精细调整。文章展示了具体的布局设计和代码实现,帮助开发者更好地理解和应用图像处理技术。 ... [详细]
  • 本文介绍了如何通过掌握 IScroll 技巧来实现流畅的上拉加载和下拉刷新功能。首先,需要按正确的顺序引入相关文件:1. Zepto;2. iScroll.js;3. scroll-probe.js。此外,还提供了完整的代码示例,可在 GitHub 仓库中查看。通过这些步骤,开发者可以轻松实现高效、流畅的滚动效果,提升用户体验。 ... [详细]
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • MySQL性能优化与调参指南【数据库管理】
    本文详细探讨了MySQL数据库的性能优化与参数调整技巧,旨在帮助数据库管理员和开发人员提升系统的运行效率。内容涵盖索引优化、查询优化、配置参数调整等方面,结合实际案例进行深入分析,提供实用的操作建议。此外,还介绍了常见的性能监控工具和方法,助力读者全面掌握MySQL性能优化的核心技能。 ... [详细]
  • 本文深入探讨了 HTML 中的 `margin` 属性,详细解析了其基本特性和应用场景。文章不仅介绍了 `margin` 的基本概念,还重点讨论了垂直外边距合并现象,并分析了 `margin` 在块级元素与内联元素中的不同表现。通过实例和代码示例,帮助读者全面理解 `margin` 的使用技巧和常见问题。 ... [详细]
  • 在IntelliJ IDEA中初始化Git并将项目推送到远程仓库的具体步骤包括:首先,登录Gitee(码云)账号并创建新的仓库;接着,在IDEA中通过VCS菜单选择Git进行本地项目的初始化;最后,配置远程仓库地址并执行推送操作,确保项目代码安全上传至云端。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • 在上篇文章的基础上,本文将继续探讨 Linux 设备驱动中的设备模型与 `devicedriverbus` 机制。在将设备注册到总线之前,需要先创建 `device` 对象。可以通过静态定义 `device` 结构体变量,并调用 `device_register` 函数来完成这一过程。此外,文章还将详细解析设备模型的内部工作机制,以及 `devicedriverbus` 机制如何实现设备与驱动的自动匹配和管理。 ... [详细]
  • iOS开发中常用的设备标识符(IDFA、IDFV、MAC地址、UDID、openUDID)及其应用场景
    在iOS开发过程中,了解并合理使用各种设备标识符对于数据统计和用户分析至关重要。本文详细介绍了几种常用的设备标识符及其应用场景:IDFA(广告标识符)用于广告追踪和归因;IDFV(供应商标识符)适用于同一应用或同一开发者旗下的应用内识别用户;MAC地址和UDID(唯一设备标识符)虽然已被弃用,但在某些历史场景下仍有参考价值;而openUDID作为一种开源解决方案,提供了一种替代UDID的方法。这些标识符各有特点,开发者应根据具体需求选择合适的标识符。 ... [详细]
  • 本文深入探讨了 Android DrawingView 的优化技巧与实现方法,重点介绍了如何实现平滑绘制效果。通过支持常见的绘图工具和形状,以及图层变换功能,提升了用户体验。文章详细解析了绘制过程中的性能优化策略,包括减少重绘次数、使用硬件加速和优化内存管理等技术,为开发者提供了实用的参考。 ... [详细]
author-avatar
国务二局
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有