iOS: 热门搜索标签界面(Swift3)

2023-11-03 07:00

本文主要是介绍iOS: 热门搜索标签界面(Swift3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里写图片描述

首先创建一个SearchView类,这个类分为上面的标题文字和下面的按钮.按钮的数量是不确定的,在将按钮添加到SearchView之前先记录下这个按钮的maxX加上横向间距的值和y值,在布局下一个按钮的时候先判断这一行余下的距离是否大于这个按钮的宽度,也就是SearchView视图的宽度减去上一个按钮的maxX加上横向间距的值是否大于这个按钮的宽度.如果大于就是说剩下的距离可以放下这个按钮,那么这个按钮的x值就是上一个按钮的maxX加上横向间距,y值与上一个按钮相同;如果小于就是说剩下的距离放不下这个按钮,那么就将这个按钮放到下一行,这个按钮的x值就是0,y值就是上一个按钮的y值加上纵向间距和按钮的高度.整个SearchView视图的高度是最后一个按钮的maxY.

class SearchView: UIView {//标题private let titleLabel = UILabel()//上一个按钮的maxX加上间距private var lastX: CGFloat = 0//上一个按钮的y值private var lastY: CGFloat = 35//按钮的回调blockprivate var btnCallBackBlock: ((_ btn: UIButton) -> ())?//SearchView的总高度var searchViewHeight: CGFloat = 0override init(frame: CGRect) {super.init(frame: frame)titleLabel.frame = CGRect(x: 0, y: 0, width: frame.size.width - 30, height: 35)titleLabel.font = UIFont.systemFont(ofSize: 15)titleLabel.textColor = UIColor(red: 140 / 255.0, green: 140 / 255.0, blue: 140 / 255.0, alpha: 1)addSubview(titleLabel)}required init?(coder aDecoder: NSCoder) {fatalError("init(coder:) has not been implemented")}convenience init(frame: CGRect, titleLabelText: String, btnTexts: [String], btnCallBackBlock: @escaping ((_ sender: UIButton) -> ())) {self.init(frame: frame)titleLabel.text = titleLabelText//按钮文字的宽度var btnW: CGFloat = 0//按钮的高度let btnH: CGFloat = 30//文字与按钮两边的距离之和let addW: CGFloat = 30//横向间距let marginX: CGFloat = 10//纵向间距let marginY: CGFloat = 10for i in 0..<btnTexts.count {let btn = UIButton(type: .custom)btn.setTitle(btnTexts[i], for: .normal)btn.setTitleColor(UIColor.black, for: .normal)btn.titleLabel?.font = UIFont.systemFont(ofSize: 14)btn.titleLabel?.sizeToFit()btn.backgroundColor = UIColor.whitebtn.layer.cornerRadius = 15btn.layer.masksToBounds = truebtn.layer.borderWidth = 0.5btn.layer.borderColor = UIColor(red: 200 / 255.0, green: 200 / 255.0, blue: 200 / 255.0, alpha: 1).cgColorbtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)//按钮的总宽度btnW = (btn.titleLabel?.bounds.width)! + addW//在给按钮的frame赋值之前先判断本行余下的宽度是否大于将要布局的按钮的宽度,如果大于则x值为上一个按钮的宽度加上横向间距,y值与上一个按钮相同,如果小于则x值为0,y值为上一个按钮的y值加上按钮的高度和纵向间距if frame.width - lastX > btnW {btn.frame = CGRect(x: lastX, y: lastY, width: btnW, height: btnH)} else {btn.frame = CGRect(x: 0, y: lastY + marginY + btnH, width: btnW, height: btnH)}lastX = btn.frame.maxX + marginXlastY = btn.frame.origin.ysearchViewHeight = btn.frame.maxYaddSubview(btn)}self.btnCallBackBlock = btnCallBackBlock}@objc private func btnClick(sender: UIButton) {btnCallBackBlock!(sender)}
}

点击热门搜索视图的按钮会发生四件事: 1.将按钮文字显示到搜索框 2.将按钮文字写入到偏好设置 3.在历史记录中显示按钮 4.更新清空历史按钮的状态

常量

    let UIScreenBounds: CGRect = UIScreen.main.boundslet KNavigationBarBackgroundColor = UIColor(red: 249 / 255.0, green: 250 / 255.0, blue: 253 / 255.0, alpha: 1)let KGlobalBackgroundColor = UIColor(red: 239 / 255.0, green: 239 / 255.0, blue: 239 / 255.0, alpha: 1)let HistorySearch = "HistorySearch"

把ScrollView添加到视图中

private func setup() {               navigationController?.navigationBar.barTintColor = KNavigationBarBackgroundColorview.backgroundColor = KGlobalBackgroundColorview.addSubview(scrollView)scrollView.addSubview(cleanHistoryButton)}     lazy var scrollView: UIScrollView = {let scrollView = UIScrollView(frame: UIScreen.main.bounds)scrollView.alwaysBounceVertical = truescrollView.backgroundColor = UIColor(red: 239 / 255.0, green: 239 / 255.0, blue: 239 / 255.0, alpha: 1)scrollView.delegate = selfreturn scrollView}()

搜索框

    lazy var searchBar: UISearchBar = {let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width * 0.9, height: 30))searchBar.placeholder = "请输入商品名称"searchBar.barTintColor = UIColor.whitesearchBar.keyboardType = .defaultsearchBar.delegate = selfreturn searchBar}()//SearchBar代理方法func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {if (searchBar.text?.characters.count)! > 0 {//将搜索框文字写入到偏好设置writeHistorySearchToUserDefaults(str: searchBar.text!)}}private func setupTilteView() {let bgView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreenBounds.width, height: 30))bgView.backgroundColor = UIColor.whitebgView.layer.masksToBounds = truebgView.layer.cornerRadius = 6bgView.layer.borderColor = UIColor(red: 100 / 255.0, green: 100 / 255.0, blue: 100 / 255.0, alpha: 1).cgColorbgView.layer.borderWidth = 0.2UIGraphicsBeginImageContext(bgView.bounds.size)bgView.layer.render(in: UIGraphicsGetCurrentContext()!)let bgImage = UIGraphicsGetImageFromCurrentImageContext()searchBar.setSearchFieldBackgroundImage(bgImage, for: .normal)navigationItem.titleView = searchBar}

热门搜索视图

    var hotSearchView: SearchView?private func setupHotSearchView() {//如果偏好设置为空写入一个空数组var historySearch = UserDefaults.standard.object(forKey: HistorySearch) as? [String]if historySearch == nil {historySearch = [String]()UserDefaults.standard.set(historySearch, forKey: HistorySearch)}//标签的标题 可以从服务器获得let arr = ["年货大集", "酸奶", "水", "车厘子", "洽洽瓜子", "维他", "香烟", "周黑鸭", "草莓", "星巴克", "卤味"]hotSearchView = SearchView(frame: CGRect(x: 10, y: 40, width: UIScreenBounds.width - 20, height: 100), titleLabelText: "热门搜索", btnTexts: arr, btnCallBackBlock: { [weak self](btn) inlet str = btn.title(for: .normal)//将按钮文字显示到搜索框self?.searchBar.text = str//将按钮文字写入到偏好设置   self?.writeHistorySearchToUserDefaults(str: str!)})hotSearchView?.bounds.size.height = (hotSearchView?.searchViewHeight)!scrollView.addSubview(hotSearchView!)}

将历史搜索写入到偏好设置

    //将历史搜索写入偏好设置private func writeHistorySearchToUserDefaults(str: String) {//从偏好设置中读取var historySearch = UserDefaults.standard.object(forKey: HistorySearch) as? [String]//如果已经存在就不重复写入for text in historySearch! {if text == str {return}}historySearch!.append(str)UserDefaults.standard.set(historySearch, forKey: HistorySearch)setupHistorySearchView()}

历史记录视图

    var historySearchView: SearchView?private func setupHistorySearchView() {if historySearchView != nil {historySearchView?.removeFromSuperview()historySearchView = nil}//从偏好设置中读取let arr = UserDefaults.standard.object(forKey: HistorySearch) as! [String]if arr.count > 0 {historySearchView = SearchView(frame: CGRect(x: 10, y: (hotSearchView?.frame.maxY)! + 20, width: UIScreenBounds.width - 20, height: 0), titleLabelText: "历史记录", btnTexts: arr, btnCallBackBlock: { [weak self](btn) inlet str = btn.title(for: .normal)self?.searchBar.text = str})historySearchView?.frame.size.height = (historySearchView?.searchViewHeight)!scrollView.addSubview(historySearchView!)updateCleanHistoryButton(hidden: false)}}

更新清空历史视图状态

    private func updateCleanHistoryButton(hidden: Bool) {if historySearchView != nil {cleanHistoryButton.frame = CGRect(x: 0.1 * UIScreenBounds.width, y: (historySearchView?.frame.maxY)! + 20, width: UIScreenBounds.width * 0.8, height: 40)}cleanHistoryButton.isHidden = hidden}

清空历史按钮

    lazy var cleanHistoryButton: UIButton = {let cleanHistoryButton = UIButton(type: .custom)cleanHistoryButton.setTitle("清 空 历 史", for: .normal)cleanHistoryButton.setTitleColor(UIColor(red: 153 / 255.0, green: 153 / 255.0, blue: 153 / 255.0, alpha: 1), for: .normal)cleanHistoryButton.titleLabel?.font = UIFont.systemFont(ofSize: 14)cleanHistoryButton.backgroundColor = UIColor(red: 239 / 255.0, green: 239 / 255.0, blue: 239 / 255.0, alpha: 1)cleanHistoryButton.layer.cornerRadius = 5cleanHistoryButton.layer.borderColor = UIColor(red: 200 / 255.0, green: 200 / 255.0, blue: 200 / 255.0, alpha: 1).cgColorcleanHistoryButton.layer.borderWidth = 0.5cleanHistoryButton.isHidden = truecleanHistoryButton.addTarget(self, action: #selector(cleanHistory), for: .touchUpInside)return cleanHistoryButton}()@objc private func cleanHistory() {var historys = UserDefaults.standard.object(forKey: HistorySearch) as? [String]historys?.removeAll()UserDefaults.standard.set(historys, forKey: HistorySearch)setupHistorySearchView()updateCleanHistoryButton(hidden: true)}

这篇关于iOS: 热门搜索标签界面(Swift3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/336429

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

AI Toolkit + H100 GPU,一小时内微调最新热门文生图模型 FLUX

上个月,FLUX 席卷了互联网,这并非没有原因。他们声称优于 DALLE 3、Ideogram 和 Stable Diffusion 3 等模型,而这一点已被证明是有依据的。随着越来越多的流行图像生成工具(如 Stable Diffusion Web UI Forge 和 ComyUI)开始支持这些模型,FLUX 在 Stable Diffusion 领域的扩展将会持续下去。 自 FLU

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序