首页 > 解决方案 > Ho to create single tableview for two UISegment Control with two different selection check mark using Swift?

问题描述

I am maintaining UISegmentControl and Search with a single tableview. Here, I am loading the tableview data from a JSON (language list).

Now I have two segment buttons like Source language and Target language and both segments tableviews also have same data. Here, whenever user selects source language a particular row is check marked and if then user clicks target language segment, the same check mark shows. I need to maintain separate data selections, also, I am going to use search bar.

Can you please provide me a solution for two different segment controller buttons but maintaining a single tableview and its data and UI look the same. Checkmark selection should be different and persistent.

enter image description here

My Code

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "languagecell", for: indexPath) as! LangCustomCell

    let item = langData[indexPath.row]

    cell.flag_img.sd_setImage(with:url, placeholderImage: UIImage(named: "usa.png"))
    cell.language_label.text = item.languageName
    cell.language_label.textColor = UIColor.gray
    cell.selectionStyle = .none

    //configure you cell here.
    if(indexPath.row == selectedIndex) {
        cell.accessoryType = .checkmark
    } else {
        cell.accessoryType = .none
    }
    return cell
} 

标签: swift

解决方案


Create two separate variables to store selected languages for from and to. In tableView didSelectRowAt method check save in appropriate variable based on the selectedSegmentIndex. In TableView cellForRowAt check the selected languages with current language. If selectedSegmentIndex and selected language matches use .checkmark else use .none

And create two arrays with type [Language]. In searchBar textDidChange method filter the languages array and reload the tableView.

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
    struct Language: Equatable {
        var title: String
        var icon: UIImage?
    }
    var allLanguages = [Language]()
    var filteredLanguages = [Language]()
    var selectedFromLanguage:Language?
    var selectedToLanguage:Language?

    let segmentedControl = UISegmentedControl()
    let tableView = UITableView()
    let searchBar = UISearchBar()

    override func viewDidLoad() {
        super.viewDidLoad()
        allLanguages = [Language(title: "English", icon: UIImage(named:"uk"))]
        filteredLanguages = allLanguages
//      add constraints segmentedControl, tableView, searchBar in view
    }
    // MARK: - Table view data source
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return filteredLanguages.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
        cell.textLabel?.text = filteredLanguages[indexPath.row].title
        cell.imageView?.image = filteredLanguages[indexPath.row].icon
        if segmentedControl.selectedSegmentIndex == 0 && selectedFromLanguage == filteredLanguages[indexPath.row] {
            cell.accessoryType = .checkmark
        } else if segmentedControl.selectedSegmentIndex == 1 && selectedToLanguage == filteredLanguages[indexPath.row] {
            cell.accessoryType = .checkmark
        } else {
            cell.accessoryType = .none
        }
        return cell
    }
    // MARK: - Table view Delegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if segmentedControl.selectedSegmentIndex == 0 {//from
            selectedFromLanguage = filteredLanguages[indexPath.row]
        } else {//to
            selectedToLanguage = filteredLanguages[indexPath.row]
        }
        tableView.reloadData()
    }
    // MARK: - Search bar Delegate
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText.isEmpty {
            filteredLanguages = allLanguages
        } else {
            filteredLanguages = allLanguages.filter({ $0.title.localizedCaseInsensitiveContains(searchText) })
        }
        tableView.reloadData()
    }
}

Use computed properties like this to persist the selected languages

var selectedFromLanguage:Language? {
    get {
        if let data = UserDefaults.standard.value(forKey: "fromLanguage") as? Data,
            let language = try? JSONDecoder().decode(Language.self, from: data) {
            return language
        }
        return nil 
    }
    set {
        if let data = try? JSONEncoder().encode(newValue) {
            UserDefaults.standard.set(data, forKey: "fromLanguage")
        }
    }
}
var selectedToLanguage:Language? {
    get {
        if let data = UserDefaults.standard.value(forKey: "toLanguage") as? Data,
            let language = try? JSONDecoder().decode(Language.self, from: data) {
            return language
        }
        return nil
    }
    set {
        if let data = try? JSONEncoder().encode(newValue) {
            UserDefaults.standard.set(data, forKey: "toLanguage")
        }
    }
}

推荐阅读