如何使搜索栏标题与单元格在同一部分中工作?

时间:2018-07-24 00:42:46

标签: ios swift uicollectionview uicollectionviewcell uisearchbar

我有一个标题,其中包含一个搜索栏,可以搜索单元格。但是,使搜索栏起作用的唯一方法是将其作为节头放置在与所查找的单元格不同的节中。是否可以将搜索栏及其单元格放在同一部分。谢谢您预先提供的所有帮助。

以下代码:

import UIKit

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate, UISearchBarDelegate {

    lazy var collectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.sectionHeadersPinToVisibleBounds = true
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .white
        cv.delegate = self
        cv.dataSource = self
        return cv
    }()

    var genericTagsArray:[String] = ["tag1","tag2","tag3","tag4","tag5","tag6","tag7","tag8","tag9","tag10","tag11","tag12","A","B","C","D","E","F","G","Ab","Abc","za","tag1","tag2","tag3","tag4","tag5","tag6","tag7","tag8","tag9","tag10","tag11","tag12","A","B","C","D","E","F","G","Ab","Abc","za"]

    var currentTagsArray:[String] = [String]() {
        didSet {
            collectionView.reloadSections(IndexSet.init(integer: 1))
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(collectionView)
        collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
        collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header")
        collectionView.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: self.view.leadingAnchor, bottom: self.view.bottomAnchor, trailing: self.view.trailingAnchor, padding: .init(top: 0, left: 0, bottom: 0, right: 0))
        collectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)


    }


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if section == 0 { return 0 }
        return currentTagsArray.count
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
    var header:Header = Header()
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header", for: indexPath) as! Header
        header.searchBar.delegate = self
        return header
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        if section == 0 {
            return CGSize(width: self.view.frame.width, height: 50)
        }
        return CGSize()
    }


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
        cell.label.text = currentTagsArray[indexPath.item]
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        return CGSize(width: self.view.frame.size.width, height: 50)

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 5
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 5
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        self.currentTagsArray = self.genericTagsArray.filter { (text) -> Bool in
            return text.contains(searchText.lowercased())
        }
    }


}

class Cell : UICollectionViewCell {

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {
        self.backgroundColor = .gray
        self.addSubview(label)
        label.anchor(top: self.topAnchor, leading: self.leadingAnchor, bottom: self.bottomAnchor, trailing: self.trailingAnchor)
    }

}

class Header : UICollectionViewCell {

    let searchBar = UISearchBar()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {
        self.backgroundColor = .gray
        self.addSubview(searchBar)
        searchBar.anchor(top: self.topAnchor, leading: self.leadingAnchor, bottom: self.bottomAnchor, trailing: self.trailingAnchor)
    }

}

extension UIView {
    func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) {
        translatesAutoresizingMaskIntoConstraints = false

        if let top = top {
            topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
        }

        if let leading = leading {
            leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
        }

        if let bottom = bottom {
            bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true
        }

        if let trailing = trailing {
            trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true
        }

        if size.width != 0 {
            widthAnchor.constraint(equalToConstant: size.width).isActive = true
        }

        if size.height != 0 {
            heightAnchor.constraint(equalToConstant: size.height).isActive = true
        }
    }
}

1 个答案:

答案 0 :(得分:1)

将搜索放在其中一个单元格内不是好习惯。话虽如此,您甚至可以尝试这样的尝试,甚至感觉很hack:

var currentTagsArray:[String] = [String]() {
    didSet {
        collectionView.reloadData()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addSubview(collectionView)
    collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
    collectionView.register(Header.self, forCellWithReuseIdentifier: "\(Header.self)")
    collectionView.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: self.view.leadingAnchor, bottom: self.view.bottomAnchor, trailing: self.view.trailingAnchor, padding: .init(top: 0, left: 0, bottom: 0, right: 0))
    collectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return currentTagsArray.count + 1
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

    return CGSize(width: self.view.frame.width, height: 50)
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    if indexPath.section == 0 && indexPath.item == 0 {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "\(Header.self)", for: indexPath) as! Header
        cell.searchBar.delegate = self
        searchCell = cell

        DispatchQueue.main.async {
            if self.currentTagsArray.count != 0 {
                self.searchCell?.searchBar.becomeFirstResponder()
            }
        }

        return cell
    }

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
    cell.label.text = currentTagsArray[indexPath.item - 1]
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    return CGSize(width: self.view.frame.size.width, height: 50)
}

别忘了删除标题的逻辑。

要再次强调这一点,这不是一个好习惯,因此使用风险自负。