Search code examples
iosswiftuitableviewuisplitviewcontroller

Using Tableview of a UISplitViewController as a filter


I'm putting UISplitViewControllers in UITabBarController.

enter image description here

I'm Trying to use the master view as a filter. So I used cellAccessoryType as check mark . Only one among all can be selected. the code that i wrote for this is

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.selectedIndex = indexPath.row

    let cell:UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)!
    cell.accessoryType = .Checkmark
    self.performSegueWithIdentifier("dispAccounts", sender: self)
        }
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    let cell:UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)!
    cell.accessoryType = .None
}
override func viewDidLoad() {
    super.viewDidLoad()
    filterList = ["All Accounts","Business Accounts","Person Accounts"]
    self.tableView.allowsMultipleSelection = false
    //self.splitViewController?.maximumPrimaryColumnWidth = 140; //This line is to restrict the width of master View of UISplitVC
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 3
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("accountCell", forIndexPath: indexPath)

    cell.textLabel?.text = filterList[indexPath.row]
    return cell
}

Now Once I select 'All Account' cell,Then I move to another tab 'Call' Then I comeback to 'Account' tab, then I select 'Business Accounts' it is getting selected and checkmark is also updating but the problem is 'All accounts' cell's check mark is not getting vanished.


Solution

  • This bug occurs due to the optimisations that have been implemented into UITableView and UITableViewCell. These two views are highly efficient and one way that Apple has made them so efficient is by reusing the cells instead of instantiating new cells all the time (that's why you are calling dequeueReusableCellWithIdentifier instead of instantiating a new cell every time).

    In order to overcome this bug, then you have to reset the cells every time they are used.

    This can be done in two ways:

    • OverwritingprepareForReuse if you were subclassing UITableViewCell (but this is not an option for you since you are using the standard UITableViewCell)
    • Resetting the properties directly in cellForRowAtIndexPath

    So a possible solution for you could look like the following:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Getting the cell
        let cell = tableView.dequeueReusableCellWithIdentifier("accountCell", forIndexPath: indexPath)
    
        // Resetting the cell
        cell.textLabel?.text = ""
        cell.selected = false
    
        // Configuring the cell
        cell.textLabel?.text = filterList[indexPath.row]
    
        // Returning the finished cell
        return cell
    }