先上图:
清空标签之后:
代码:
BKSearchViewController.swift
class BKSearchViewController: UIViewController {
// 引导搜索
var guide: BKSearchGuideView!
// 实时标签
var mark: BKSearchNewMarkView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .groupTableViewBackground
setupNavigationbar()
setupSearchNewMarks()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
BKSearchNewMarkViewModel.totalWidth = 0.px
BKSearchNewMarkViewModel.totalHeight = 0.px
}
}
//MARK: ---------- 导航栏 ----------
extension BKSearchViewController: BKNavigationBarable {
func setupNavigationbar() {
guard let navBar = navigationController?.navigationBar else { return }
let frame = CGRect(x: 0, y: 0,
width: BK_SCREEN_WIDTH,
height: BK_NAVBAR_HEIGHT(navBar.bounds.height))
let nav = BKSearchNavigationBar(frame: frame)
nav.delegate = self
view.addSubview(nav)
}
}
//MARK: ---------- 搜索导航引导层 ----------
extension BKSearchViewController {
fileprivate func setupSearchGuideView() {
guard let navBar = navigationController?.navigationBar else { return }
guide = BKSearchGuideView()
view.addSubview(guide)
guide.snp.makeConstraints { make in
make.top.equalTo(view).offset(BK_NAVBAR_HEIGHT(navBar.bounds.height))
make.left.right.bottom.equalTo(view)
}
}
}
//MARK: ---------- 实时标签 ----------
extension BKSearchViewController: BKSearchNewMarkable {
fileprivate func setupSearchNewMarks() {
guard let navBar = navigationController?.navigationBar else { return }
mark = BKSearchNewMarkView()
mark.delegate = self
view.addSubview(mark)
mark.snp.makeConstraints { make in
make.top.equalTo(view).offset(BK_NAVBAR_HEIGHT(navBar.bounds.height))
make.left.right.bottom.equalTo(view)
}
}
// 代理 清空标签
func searchNewMarkClearMarks() {
let alertController = UIAlertController(title: nil, message: "确定要清空标签吗?", preferredStyle: .alert)
let okAction = UIAlertAction(title: "确定", style: .default) { [weak self] (action) in
self?.mark.removeFromSuperview()
self?.setupSearchGuideView()
}
alertController.addAction(okAction)
alertController.addAction(UIAlertAction(title: "取消", style: .destructive, handler: nil))
present(alertController, animated: true, completion: nil)
}
}
//MARK: ---------- 搜索回调代理函数 ----------
extension BKSearchViewController: BKSearchNavigationBarable {
func searchNavigationBarBack() {
navigationController?.popViewController(animated: true)
}
func searchNavigationBarSearch(content: String) {
print("正在搜索...")
}
}
BKSearchViewModel.swift
//MARK: ---------- 搜索的导航栏 ----------
protocol BKSearchNavigationBarable: class {
/// 返回
func searchNavigationBarBack()
/// 搜索
func searchNavigationBarSearch(content: String)
}
class BKSearchNavigationBar: UIView {
/// 返回按钮
var backButton: UIButton!
/// 搜索框
var searchTextFiled: UITextField!
/// 搜索按钮
var searchButton: UIButton!
/// 返回和搜索的代理
var delegate: BKSearchNavigationBarable?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
// 返回按钮
backButton = UIButton(type: .custom)
backButton.setImage(#imageLiteral(resourceName: "icon_header_back"), for: .normal)
backButton.setTitleColor(.darkGray, for: .normal)
backButton.addTarget(self, action: #selector(backButtonPressed), for: .touchUpInside)
backButton.imageEdgeInsets = BK_BACK_EDGEINSET
addSubview(backButton)
// 搜索按钮
searchButton = UIButton(type: .custom)
searchButton.setTitle("搜索", for: .normal)
searchButton.setTitleColor(.darkGray, for: .normal)
searchButton.titleLabel?.font = UIFont.systemFont(ofSize: 13.f)
searchButton.addTarget(self, action: #selector(searchButtonPressed), for: .touchUpInside)
addSubview(searchButton)
// 搜索框
let leftView = UIImageView(image: #imageLiteral(resourceName: "icon_header_search"))
leftView.contentMode = .scaleAspectFit
leftView.frame = CGRect(x: 10.px, y: 10.px,
width: frame.height-BK_STATUS_HEIGHT-15.px,
height: frame.height-BK_STATUS_HEIGHT-20.px)
searchTextFiled = UITextField()
searchTextFiled.backgroundColor = .groupTableViewBackground
searchTextFiled.font = UIFont.systemFont(ofSize: 13.f)
searchTextFiled.textColor = .lightGray
searchTextFiled.textAlignment = .left
searchTextFiled.layer.cornerRadius = (frame.height-BK_STATUS_HEIGHT-16.px)/2.px
searchTextFiled.layer.masksToBounds = true
searchTextFiled.placeholder = "搜索"
searchTextFiled.leftView = leftView
searchTextFiled.leftViewMode = .always
addSubview(searchTextFiled)
backButton.snp.makeConstraints { make in
make.left.bottom.equalTo(self)
make.width.height.equalTo(frame.height-BK_STATUS_HEIGHT)
}
searchButton.snp.makeConstraints { make in
make.right.bottom.equalTo(self)
make.width.height.equalTo(frame.height-BK_STATUS_HEIGHT)
}
searchTextFiled.snp.makeConstraints { make in
make.left.equalTo(backButton.snp.right)
make.right.equalTo(searchButton.snp.left).offset(-5.px)
make.height.equalTo(frame.height-BK_STATUS_HEIGHT-16.px)
make.bottom.equalTo(self).offset(-8.px)
}
}
/// 点击返回按钮 返回到上一页
@objc private func backButtonPressed() {
guard let delegate = delegate else { return }
delegate.searchNavigationBarBack()
}
/// 点击搜索按钮 开始进行内容搜索
@objc private func searchButtonPressed() {
guard let delegate = delegate else { return }
if let content = searchTextFiled.text {
if content.count > 0 {
delegate.searchNavigationBarSearch(content: content)
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK: ---------- 展示搜索的引导 文章 视频 自媒体 ----------
class BKSearchGuideView: UIView {
/// 头
var titleLable: UILabel!
/// 引导内容层
var guideView: UIView!
override init(frame: CGRect) {
super.init(frame: frame)
// 头
titleLable = UILabel()
titleLable.text = "搜索感兴趣的内容"
titleLable.textAlignment = .center
titleLable.font = UIFont.systemFont(ofSize: 17.f)
titleLable.textColor = .darkGray
addSubview(titleLable)
// 引导内容层
guideView = UIView()
addSubview(guideView)
titleLable.snp.makeConstraints { make in
make.top.equalTo(self).offset(40.px)
make.left.right.equalTo(self)
make.height.equalTo(17.px)
}
guideView.snp.makeConstraints { make in
make.top.equalTo(titleLable.snp.bottom).offset(20.px)
make.left.equalTo(self).offset(60.px)
make.width.equalTo(BK_SCREEN_WIDTH-120.px)
make.height.equalTo(80.px)
}
// 引导内容
let width = (BK_SCREEN_WIDTH-120.px)/(BKSearchGuideViewModel.guideTitles.count).px
for (i, v) in BKSearchGuideViewModel.guideTitles.enumerated() {
let imageView = UIImageView(image: UIImage(named: BKSearchGuideViewModel.guideImages[i]))
imageView.contentMode = .scaleAspectFit
guideView.addSubview(imageView)
let label = UILabel()
label.text = v
label.textColor = .lightGray
label.font = UIFont.systemFont(ofSize: 15.f)
label.textAlignment = .center
guideView.addSubview(label)
imageView.snp.makeConstraints { make in
make.left.equalTo(guideView).offset(width*i.px)
make.top.equalTo(guideView).offset(10.px)
make.width.equalTo(width)
make.height.equalTo(width-35.px)
}
label.snp.makeConstraints { make in
make.left.equalTo(guideView).offset(width*i.px)
make.width.equalTo(width)
make.bottom.equalTo(guideView)
make.height.equalTo(20.px)
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK: ---------- 实时标签 ----------
protocol BKSearchNewMarkable: class {
func searchNewMarkClearMarks()
}
class BKSearchNewMarkView: UIView {
/// 标签底层View
var markView: UIView!
/// 清楚标签按钮
var clearMarkButton: UIButton!
/// 代理
var delegate: BKSearchNewMarkable?
override init(frame: CGRect) {
super.init(frame: frame)
// 标签底层View
markView = UIView()
addSubview(markView)
markView.snp.makeConstraints { make in
make.top.equalTo(self).offset(20.px)
make.left.equalTo(self).offset(10.px)
make.right.equalTo(self).offset(-10.px)
make.height.equalTo(200.px)
}
// 绘制实时标签
var tempTotalWidth: CGFloat = 0.px
BKSearchNewMarkViewModel.testNewMarks.forEach { value in
let label = UILabel()
label.text = value
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 12.f)
label.textColor = .lightGray
label.backgroundColor = .white
label.layer.cornerRadius = 10.px
label.layer.masksToBounds = true
markView.addSubview(label)
let markWidth = BKSearchNewMarkViewModel.getLabelWidth(value.count)+10.px
tempTotalWidth += markWidth
if tempTotalWidth > (BK_SCREEN_WIDTH-20.px) {
tempTotalWidth = markWidth
BKSearchNewMarkViewModel.totalHeight += 30.px
BKSearchNewMarkViewModel.totalWidth = 0.px
}
label.snp.makeConstraints { make in
make.top.equalTo(markView).offset(BKSearchNewMarkViewModel.totalHeight)
make.left.equalTo(markView).offset(BKSearchNewMarkViewModel.totalWidth)
make.width.equalTo(BKSearchNewMarkViewModel.getLabelWidth(value.count))
make.height.equalTo(20.px)
}
// 累加每行的总长度
BKSearchNewMarkViewModel.totalWidth += markWidth
}
// 更新高度
markView.snp.updateConstraints { make in
make.height.equalTo(BKSearchNewMarkViewModel.totalHeight+20.px)
}
// 清除标签按钮
clearMarkButton = UIButton(type: .custom)
clearMarkButton.setTitle("清空标签", for: .normal)
clearMarkButton.titleLabel?.font = UIFont.systemFont(ofSize: 13.f)
clearMarkButton.setTitleColor(UIColor(32, 167, 250), for: .normal)
clearMarkButton.addTarget(self, action: #selector(clearMarkButtonPressed), for: .touchUpInside)
addSubview(clearMarkButton)
clearMarkButton.snp.makeConstraints { make in
make.centerX.equalTo(self)
make.top.equalTo(markView.snp.bottom).offset(10.px)
make.width.equalTo(100.px)
make.height.equalTo(45.px)
}
}
@objc private func clearMarkButtonPressed() {
guard let delegate = delegate else { return }
delegate.searchNewMarkClearMarks()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
BKSearchViewModel.swift
//MARK: ---------- 展示搜索的引导 文章 视频 自媒体 ----------
struct BKSearchGuideViewModel {
/// 引导内容头
static let guideTitles = ["文章", "视频", "自媒体"]
/// 引导内容图片
static let guideImages = ["icon_search_article", "icon_search_video", "icon_search_wemedia"]
}
//MARK: ---------- 实时标签 ----------
struct BKSearchNewMarkViewModel {
/// 实时标签
static let testNewMarks = ["还珠格格", "春运", "张学良",
"德云社相声", "水哥集锦", "水哥最强大脑",
"抖音短视频", "蜘蛛侠", "老梁说天下",
"郭德纲", "智行火车票", "58同城",
"快牙", "百词斩", "微博",
"虾米音乐", "淘宝大学", "千牛",
"阿里巴巴", "旺信", "工具",
"快手"]
/// 一行的总长度
static var totalWidth: CGFloat = 0.px
/// 累加高度
static var totalHeight: CGFloat = 0.px
static func getLabelWidth(_ count: Int) -> CGFloat {
switch count {
case 1:
return 40.px
case 2:
return 50.px
case 3:
return 60.px
case 4:
return 70.px
case 5:
return 80.px
case 6:
return 90.px
default:
return 100.px
}
}
}