Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I delete a default checkmark when I choose a new one in a UITableViewController in Swift 3.0?

Purpose

I am making an iPhone App in Swift 3.0 and Xcode 8.0. Now, I want to make a setting menu for choosing color using a table view controller.

I want to allow only one cell (color) to be selecable in this menu. I already set a default choice to "Green". When users open a setting menu at first, the selected cell (color) is green. But the user can choose a new one. (I am using UserDefaults for this function.)

Problems

When I choose a new cell, the default cell won't disappear. I want to delete this default choice when I choose a new cell. (I think other things are OK. E. g. delegates, user defaults)

My idea

I think I need to write something in the didSelectRowAt method. Maybe I need to delete all checkmarks before choosing a new one. I wrote a comment in the source below.

default selection in table view

//  TableViewControllerColorDetail.swift

import UIKit

class TableViewControllerColorDetail: UITableViewController {
    var colors = ["Purple", "White", "Blue", "Green", "Orange", "Yellow", "Red", "Black", "Pink", "Aqua", "Lapis lazuli"]
    var colorname = ""
    let userDefaults = UserDefaults.standard

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.allowsMultipleSelection = false
}

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

override func numberOfSections(in 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 colors.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ColorsDetail", for: indexPath)

    // Configure the cell...
    cell.textLabel!.text = colors[indexPath.row]

    cell.textLabel?.textColor = UIColor.white

    cell.selectionStyle = UITableViewCellSelectionStyle.none

    let savedcolornumber = userDefaults.object(forKey: "MemoryOfColornumber")
    let colornumber = indexPath.row

    //If user don’t have save data, user is using this App at first time, check to 3rd cell
    if savedcolornumber == nil {
        print("No Save Data")
        if (indexPath.row == 3) {
            cell.accessoryType = .checkmark
        } else {
            cell.accessoryType = .none
        }

    //If user have save dete
    } else {
        print("User have a Save Data")
        //Check to Save Color
            if (colornumber == savedcolornumber as! Int) {
                print("It is same as saved color")
                cell.accessoryType = .checkmark
            } else {
                print("It is NOT same as saved color")
                cell.accessoryType = .none
            }
        }

    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at:indexPath)

    // (Expect) Delete checkmarks in all cells 
    // ???????

    //  Check to selected cell
    cell?.accessoryType = .checkmark

    // Receive the text from selected cell
    let colorname = colors[indexPath.row]
    let colornumber = indexPath.row

    // Save with the key
    // Reload
    userDefaults.set(colornumber, forKey: "MemoryOfColornumber")
    userDefaults.set(colorname, forKey: "MemoryOfColorname")
    userDefaults.synchronize()

    // Export to AppDelegate
    let appDelegate:AppDelegate = UIApplication.shared.delegate as! AppDelegate 
    appDelegate.message = colorname
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at:indexPath)

    // Delete Checkmark
    cell?.accessoryType = .none
}

/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}
*/

/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        // Delete the row from the data source
        tableView.deleteRows(at: [indexPath], with: .fade)
    } else if editingStyle == .insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }    
}
*/

/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

}
*/

/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the item to be re-orderable.
    return true
}
*/

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
    */

}
like image 709
Dan Avatar asked Aug 04 '17 09:08

Dan


2 Answers

If you don't want to store previous checked indexPath then you can check with all rows also like below. Put this in didSelectRowAt indexPath

for row in 0..<tableView.numberOfRows(inSection: indexPath.section) {
    if let cell = tableView.cellForRow(at: IndexPath(row: row, section: indexPath.section)) {
        cell.accessoryType = row == indexPath.row ? .checkmark : .none
    }
}
like image 153
Jay Patel Avatar answered Sep 24 '22 14:09

Jay Patel


You should store the selected cell's index path and remove its checkmark accessory in didSelectRowAt.

var selectedIndexPath: IndexPath!

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)

    // Delete checkmarks in the previously selected cell
    if indexPath != nil,
        indexPath != selectedIndexPath,
        selectedCell = tableView.cellForRow(at: selectedIndexPath) {
        selectedCell.accessoryType = .none
        selectedIndexPath = indexPath
    }

    //  Check to selected cell
    cell?.accessoryType = .checkmark
}
like image 25
Tamás Sengel Avatar answered Sep 22 '22 14:09

Tamás Sengel