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
    //按钮的回调block
    private var btnCallBackBlock: ((_ btn: UIButton) -> ())?
    //SearchView的总高度
    var searchViewHeight: CGFloat = 0

    override 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 = 10

        for 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.white
            btn.layer.cornerRadius = 15
            btn.layer.masksToBounds = true
            btn.layer.borderWidth = 0.5
            btn.layer.borderColor = UIColor(red: 200 / 255.0, green: 200 / 255.0, blue: 200 / 255.0, alpha: 1).cgColor
            btn.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 + marginX
            lastY = btn.frame.origin.y
            searchViewHeight = btn.frame.maxY
            addSubview(btn)
        }
        self.btnCallBackBlock = btnCallBackBlock
    }

    @objc private func btnClick(sender: UIButton) {
        btnCallBackBlock!(sender)
    }
}

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

常量

    let UIScreenBounds: CGRect = UIScreen.main.bounds
    let 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 = KNavigationBarBackgroundColor
        view.backgroundColor = KGlobalBackgroundColor

        view.addSubview(scrollView)
        scrollView.addSubview(cleanHistoryButton)
    }     
        lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView(frame: UIScreen.main.bounds)
        scrollView.alwaysBounceVertical = true
        scrollView.backgroundColor = UIColor(red: 239 / 255.0, green: 239 / 255.0, blue: 239 / 255.0, alpha: 1)
        scrollView.delegate = self
        return 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.white
        searchBar.keyboardType = .default
        searchBar.delegate = self
        return 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.white
        bgView.layer.masksToBounds = true
        bgView.layer.cornerRadius = 6
        bgView.layer.borderColor = UIColor(red: 100 / 255.0, green: 100 / 255.0, blue: 100 / 255.0, alpha: 1).cgColor
        bgView.layer.borderWidth = 0.2
        UIGraphicsBeginImageContext(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) in
            let 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) in
                let 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 = 5
        cleanHistoryButton.layer.borderColor = UIColor(red: 200 / 255.0, green: 200 / 255.0, blue: 200 / 255.0, alpha: 1).cgColor
        cleanHistoryButton.layer.borderWidth = 0.5
        cleanHistoryButton.isHidden = true
        cleanHistoryButton.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)
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值