0

for a couple days now I been trying to get this working. I want to show a UICollectionView within a UITableViewController class. I have a searchbar to filter for items, but when I dismiss the searchbar, I want the collectionview to appear. I have included my entire code, maybe someone of you can help me to get this to work .. I tried calling func configureCollectionView at different places, but none of them seem to work. All the Cells I am registering are perfectly working (I know so, because they work in other controllers ..)

Thanks!!

 private let reuseIdentifier = "SearchThisCell"

class SearchController: UITableViewController, UISearchBarDelegate, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {


var item1 = [Item1]()
var searchbar = UISearchBar()
var filteredItem = [Item1]()
var inSearchMode = false
var collectionView: UICollectionView!
var collectionViewEnabled = true
var item2 = [Item2]()

override func viewDidLoad() {
    super.viewDidLoad()
    
    // register cell classes
    tableView.register(SearchThisCell.self, forCellReuseIdentifier: reuseIdentifier)

    tableView.separatorInset = UIEdgeInsets(top: 0, left: 75, bottom: 0, right: 75)
    tableView.separatorStyle = .none
    
    configureSearchBar()
    
    configureCollectionView()
    
    fetchItem1()
    
    fetchItem2()
            
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 70
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if inSearchMode {
        return filteredItem.count
    } else {
        return item1.count
    }
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
    var item: Item1!
    
    if inSearchMode {
        item = filteredItem[indexPath.row]
    } else {
        item = item1[indexPath.row]
    }
            
    let itemProfileVC = ItemProfileController(collectionViewLayout: UICollectionViewFlowLayout())
    
    itemProfileVC.item = item
    
    navigationController?.pushViewController(itemProfileVC, animated: true)
    
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! SearchThisCell
    
    var item: Item1!
    
    if inSearchMode {
        item = filteredItem[indexPath.row]
    } else {
        item = item1[indexPath.row]
    }
    
    cell.item = item1
    
    return cell
}

func configureCollectionView() {
    
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .vertical

    let frame = CGRect(x: 50, y: 50, width: view.frame.width, height: view.frame.height - (tabBarController?.tabBar.frame.height)! - (navigationController?.navigationBar.frame.height)!)

    collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.alwaysBounceVertical = true
    collectionView.backgroundColor = .white
    collectionView.register(SearchThatCell.self, forCellWithReuseIdentifier: "SearchThatCell")

    tableView.addSubview(collectionView)
    tableView.separatorColor = .clear
    
}

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

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

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = (view.frame.width - 2) / 3
    return CGSize(width: width, height: width)
}

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

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

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
    let overviewVC = OverviewController(collectionViewLayout: UICollectionViewFlowLayout())
    
    overviewVC.viewSingleItem = true
    
    overviewVC.that = item2[indexPath.item]
    
    navigationController?.pushViewController(overviewVC, animated: true)
    
}

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    searchbar.showsCancelButton = true
    
    collectionView.isHidden = false
    collectionViewEnabled = true
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    
    let searchText = searchText.lowercased()
    
    if searchText.isEmpty || searchText == " " {
        inSearchMode = false
        tableView.reloadData()
    } else {
        inSearchMode = true
        filteredItem = item.filter({ (item) in
            return item.itemname.contains(searchText)
        })
        tableView.isHidden = false
        tableView.reloadData()
    }
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchbar.endEditing(true)
    
    searchbar.showsCancelButton = false
    
    inSearchMode = false
    
    searchbar.text = nil
    
    collectionViewEnabled = true
            
    configureCollectionView()

    tableView.isHidden = true
    
    tableView.reloadData()
}

and then come the fetch functions, which are working as they supposed to.

3
  • Add a collectionview, a tableView and a searchbar as subviews of UIViewController. Set the constraints properly. Hide/unhide the tableview based on search keyword. This will be one solution. Commented Jul 31, 2021 at 9:38
  • I'm trying your solution, but I get this error: Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value Commented Jul 31, 2021 at 11:01
  • How would I correctly do your solution? @AkilanCB Commented Jul 31, 2021 at 11:01

2 Answers 2

1

You’re adding the collection view to the table view. If you hide the table view, all subviews will be hidden as well. Add the collectionview to the view of the controller instead.

change

tableView.addSubview(collectionView)

to

view.addSubview(collectionView)

It would be easier to handle both (table and collectionview) in a normal view Controller.

Sign up to request clarification or add additional context in comments.

2 Comments

You, sir @baronfac, are amazing!! It finally is working!!! Thanks a lot!!!
Glad I could help :)
1

It's better to create table cell with collection view inside.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.