Swift: find SearchBar in both sections and don't merge them

Using Swift 3, the app is a blog reader reading from a MYSQL database using PHP and JSON.

Currently my SearchBar does not do what I want, I have a search in my mainArray (section 1) with the scope "All". As filtering proceeds, objects that are being filtered are moved to filterArray. I did it at the same time because I can't figure out how to get it to do what I want.

What it should do is that when the user searches for an object, I want the object to appear in the mainArray or followArray, and not move it to another array, so it doesn't get merged. Basically filter the table view rather than deleting any partitions or merging any objects, as this will confuse the user not knowing which part of the object the object is in, and of course, make sure the scope bar is working correctly.

Learning how to implement a search bar so you can see my problem as I try to progress further. Thank!

SearchBar and Scope Code

let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
    // Search Bar
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    definesPresentationContext = true
    myTableView.tableHeaderView = searchController.searchBar
    searchController.searchBar.backgroundColor = UIColor.white
    searchController.searchBar.barTintColor = UIColor.white

    // Scope Bar
    searchController.searchBar.scopeButtonTitles = ["All", "Released", "Unreleased", "Free"]
    searchController.searchBar.delegate = self
}

// Title for Header
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    if !(searchController.isActive && searchController.searchBar.text != "") {

        if section == 0 {
            return "Followed Blogs"
        }
        else {
            return "All Blogs"
        }
    }
    return "Filtered Blogs"
}

// Number of Rows in Section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if !(searchController.isActive && searchController.searchBar.text != "") {

        if section == 0 {

            return followedArray.count
        }
        else if (section == 1) {

            return mainArray.count
        }
    }
    return filteredArray.count
}

// Number of Sections
func numberOfSections(in tableView: UITableView) -> Int {

    if !(searchController.isActive && searchController.searchBar.text != "") {

        return 2
    }
    return 1
}

// CellForRowAt indexPath
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let CellIdentifier = "Cell"
    var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! CustomCell

    if cell != cell {
        cell = CustomCell(style: UITableViewCellStyle.default, reuseIdentifier: CellIdentifier)
    }

    // Configuring the cell
    var blogObject: Blog

    if !(searchController.isActive && searchController.searchBar.text != "") {
        if indexPath.section == 0 {
            blogObject = followedArray[indexPath.row] 
            cell.populateCell(blogObject, isFollowed: true, indexPath: indexPath, parentView: self)
        }
        else if indexPath.section == 1 {
            blogObject = mainArray[indexPath.row] 
            cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
        }
    }
    else {
        blogObject = filteredArray[indexPath.row] 
        cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
    }

    return cell
}

// SEARCH BAR: Filtering Content
func filterContentForSearchText(searchText: String, scope: String = "All") {

    filteredArray = mainArray.filter { Blog in

        let categoryMatch = (scope == "All") || (Blog.blogType == scope)

        return categoryMatch && (Blog.blogName.lowercased().contains(searchText.lowercased()))
    }
    myTableView.reloadData()
}

// SEARCH BAR: Updating Results
func updateSearchResults(for searchController: UISearchController) {

    filterContentForSearchText(searchText: searchController.searchBar.text!)
}

// SEARCH BAR: Scope
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {

    filterContentForSearchText(searchText: searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}

// SEARCH BAR: Updating Scope
func updateSearchResultsForSearchController(searchController: UISearchController) {

    let searchBar = searchController.searchBar
    let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
    filterContentForSearchText(searchText: searchController.searchBar.text!, scope: scope)
}

// Deallocating Search Bar
deinit{
    if let superView = searchController.view.superview {
        superView.removeFromSuperview()
    }
}

      

+1


source to share


1 answer


At the moment you are creating a single array ( filteredArray

) and assume there is 1 section in your search.

I would rule out this assumption.

Inside your method, filterContentForSearchText

create an array of arrays (where each inner array represents a section).

Then update all methods of the table data source to work with this array of arrays to get the correct values.

First, update the declaration filteredArray

as an array of arrays.



Now update your table viewers:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if !(searchController.isActive && searchController.searchBar.text != "") {
        if section == 0 {
            return followedArray.count
        } else {
            return mainArray.count
        }
    } else {
        return filteredArray[section].count
    }
}

// Number of Sections
func numberOfSections(in tableView: UITableView) -> Int {
    if !(searchController.isActive && searchController.searchBar.text != "") {
        return 2
    } else {
        return filteredArray.count
    }
}

// CellForRowAt indexPath
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let CellIdentifier = "Cell"
    var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! CustomCell

    if cell != cell {
        cell = CustomCell(style: UITableViewCellStyle.default, reuseIdentifier: CellIdentifier)
    }

    // Configuring the cell
    var blogObject: Blog

    if !(searchController.isActive && searchController.searchBar.text != "") {
        if indexPath.section == 0 {
            blogObject = followedArray[indexPath.row] 
            cell.populateCell(blogObject, isFollowed: true, indexPath: indexPath, parentView: self)
        } else {
            blogObject = mainArray[indexPath.row] 
            cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
        }
    } else {
        blogObject = filteredArray[indexPath.section][indexPath.row] 
        cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
    }

    return cell
}

      

Finally, update the method filterContentForSearchText

:

func filterContentForSearchText(searchText: String, scope: String = "All") {
    let filteredFollowed = followedArray.filter { Blog in
        let categoryMatch = (scope == "All") || (Blog.blogType == scope)

        return categoryMatch && (Blog.blogName.lowercased().contains(searchText.lowercased()))
    }

    let filteredMain = mainArray.filter { Blog in
        let categoryMatch = (scope == "All") || (Blog.blogType == scope)

        return categoryMatch && (Blog.blogName.lowercased().contains(searchText.lowercased()))
    }

    filteredArray = [ filteredFollowed, filteredMain ]

    myTableView.reloadData()
}

      

+2


source







All Articles