Can't get the data on class uitableview Swift 3 - ios

I'm having trouble presenting the data. I have copied the code from https://stackoverflow.com/a/39307841/7118403 because i want to test his method on saving the checkmark. But unfortunately I can't present the data on tableView. When i try to print the "myItems" it shows [tableViewCheckmark.Item]. I can't seem to find the solution. PS. I'm a new to programming. Thank you in advance.
class Item {
let name : String
var selected = false
init(name: String) {
self.name = name
}
}
class TableViewController: UITableViewController {
#IBOutlet var uiTableView: UITableView!
var myItems = [Item]()
override func viewDidLoad() {
uiTableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
let item = Item(name:"Foo")
myItems.append(item)
print(myItems)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
let item = myItems[indexPath.row]
cell.textLabel!.text = item.name
cell.accessoryType = item.selected ? .checkmark : .none
cell.selectionStyle = .none
cell.tintColor = UIColor.green
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
saveDefaults()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return myItems.count
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let item = myItems[indexPath.row]
item.selected = true
tableView.reloadRows(at: [indexPath as IndexPath], with: .none)
}
func saveDefaults() {
let selectedCells = myItems.filter { $0.selected }.map { $0.name }
let defaults = UserDefaults.standard
defaults.set(selectedCells, forKey:"selectedCells")
}
func readDefaults()
{
let defaults = UserDefaults.standard
let selectedItems = defaults.stringArray(forKey: "selectedCells")!
for item in myItems {
item.selected = selectedItems.contains(item.name)
}
tableView.reloadData()
}
}

Signature of UITableViewDataSource methods is changed in Swift 3 also you are currently passing array count in numberOfSections(in:) remove it and add below methods.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
let item = myItems[indexPath.row]
cell.textLabel!.text = item.name
cell.accessoryType = item.selected ? .checkmark : .none
cell.selectionStyle = .none
cell.tintColor = UIColor.green
return cell
}
override func tableView(tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = myItems[indexPath.row]
item.selected = true
tableView.reloadRows(at: [indexPath], with: .none)
}

Related

pass text from selected tableView cell.row to fill textbox xcode

I have a tableView that allows users to make multiple selections from an array of data,
When the user clicks done, I would like the selected text to be then transferred over to another tableViews textView
Is there a way to transfer over the selected text and have the text separated by a , ?
I am coding programmatically.
var checked = [Int]()
var items = [String]()
var selectedItems = [String]()
#objc func done() {
let hud = JGProgressHUD(style: .dark)
hud.textLabel.text = "Saving!"
hud.show(in: view)
dismiss(animated: true, completion: nil)
hud.dismiss()
let aCell = aboutCell(style: .default, reuseIdentifier: nil)
aCell.textField3.text = selectedItems.joined(separator: ",")
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCell.AccessoryType.checkmark {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none
} else {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark
if selectedItems.contains(items[indexPath.row]) {
selectedItems.remove(at: selectedItems.firstIndex(of: items[indexPath.row])!)
} else {
selectedItems.append(items[indexPath.row])
}
checked.append(indexPath.row)
}
}
According to my understanding to the question, these are my thoughts:
1. First setup necessary variables
var items = [String]() // data to display in tableview
var selectedItems = [String]() // here all the selected datas are stored
2. Store the selected items data from the didSelectRowAt delegate method
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedItems.contains(items[indexPath.row]) { //check if the selected already contains the items and if contains remove it
selectedItems.remove(at: selectedItems.firstIndex(of: items[indexPath.row])!)
} else { // append the required items
selectedItems.append(items[indexPath.row])
}
// ..... other codes here
}
3. on done button
let requiredText = selectedItems.joined(separator: ",")
// pass this data through delegate method
There is no need to create an array for the selected items. You can simply call tableview method selectRow(at:animated:scrollPosition:) when selecting a row and when you need to get the selected rows just call tableview instance property indexPathsForSelectedRows. Then you just need to join the selected rows with a comma and use the resulting string in your textview or textfield. Don't forget to implement didDeselectRowAt item method as well to deselectRow.
import UIKit
class TableViewController: UITableViewController {
var items: [String] = ["1st", "2nd", "3rd", "4th", "5th"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.allowsMultipleSelection = true
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
}
func done() {
if let indexPaths = tableView.indexPathsForSelectedRows {
// note that this will preserve the order that the rows where selected. Just sort the indexPaths if you need it sorted.
let string = indexPaths.map { items[$0.row] }.joined(separator: ",")
print(string)
// your code
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCellID", for: indexPath) as! TableViewCell
cell.textLabel?.text = items[indexPath.row]
cell.accessoryType = cell.isSelected ? .checkmark : .none
return cell
}
}

swift4 uitableview retain selection

I am preparing a small app for online exams for which I need to reload the tableView for every question. Multiple selection and single selection both are needed based on question type. I was able to manage the selection type based on question type but the thing is when i reload the tableview the previous selection is replicating in the next question.
var DictItemSerialNumber = 0
let Dict = [["Question":"How many days in a week?",
"Options":["1","2","3","7"],
"QuestionType":1],
["Question":"How many days in a month?",
"Options":["28","29","30","31","32"],
"QuestionType":2],
["Question":"How many days in a Year?",
"Options":["234","265","365","400"],
"QuestionType":1]]
var SavedOptions = [String:[Any]]()
var selectedIndex:Int? = nil
override func viewDidLoad() {
super.viewDidLoad()
self.Tab.rowHeight = UITableView.automaticDimension
self.Tab.estimatedRowHeight = 300
self.Tab.tableFooterView = UIView()
self.Tab.delegate = self
self.Tab.dataSource = self
self.Tab.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
#IBAction func PrvsBtnActn(_ sender: UIButton) {
if DictItemSerialNumber > 0 {
DictItemSerialNumber -= 1
Tab.reloadData()
}
}
#IBAction func NextBtnActn(_ sender: UIButton) {
if DictItemSerialNumber < Dict.count-1{
DictItemSerialNumber += 1
Tab.reloadData()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let DictObj = Dict[DictItemSerialNumber] as NSDictionary
let optionsCount = DictObj["Options"] as! NSArray
return optionsCount.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Tab.dequeueReusableCell(withIdentifier: "cell")!
let DictObj = Dict[DictItemSerialNumber]
let qstnType = DictObj["QuestionType"] as! Int
if qstnType == 2{
self.Tab.allowsMultipleSelection = true
}else{
self.Tab.allowsMultipleSelection = false
}
QstnLbl.text = DictObj["Question"] as? String
let optionsAns = DictObj["Options"] as! NSArray
cell.textLabel?.text = optionsAns[indexPath.row] as? String
cell.selectionStyle = .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
}
}
}
question type = 1 means single selection and 2 is multiple selection

Swift - Multiple TableView checkmark - save and load choice

Im trying to save and load choice from TableView Multiple checkmarks.
I have a code ready, but I don't know how to save the selection. And how to load the selection at the opening of the list.
MY CODE:
var selectedCells = [IndexPath]()
var selectedAreas = [String]()
var Areas = [] //my text for the cells..
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return Areas.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = Areas[indexPath.row]
cell.accessoryType = selectedCells.contains(indexPath) ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
selectedCells.append(indexPath)
if selectedCell?.accessoryType == .checkmark {
if let indexremove = selectedAreas.firstIndex(of: (Areas[indexPath.row])) {
selectedAreas.remove(at: indexremove)
}
selectedCell?.accessoryType = .none
print(selectedCells)
print(selectedAreas)
print("remove ")
selectedCells = selectedCells.filter {$0 != indexPath}
} else {
print(selectedCells)
print(selectedAreas)
print("add")
selectedAreas.append(Areas[indexPath.row])
selectedCell?.accessoryType = .checkmark
}
}
Don't use multiple arrays as data source. That's pretty bad practice and inefficient.
Delete them
var selectedCells = [IndexPath]()
var selectedAreas = [String]()
Declare Area as struct and add an isSelected member
struct Area {
let name : String
var isSelected : Bool
init(name : String, isSelected : Bool = false) {
self.name = name
self.isSelected = isSelected
}
}
var areas = [Area(name: "Foo"), Area(name: "Bar")]
In cellForRowAt assign the checkmark depending on isSelected
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let area = areas[indexPath.row]
cell.textLabel?.text = area.name
cell.accessoryType = area.isSelected ? .checkmark : .none
return cell
}
In didSelectRow toggle isSelected and reload the row (yes, only two lines of code)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
areas[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
}
You get the selected areas with
let selectedAreas = areas.filter{$0.isSelected}
and an array of the names
let selectedAreaNames = areas.filter{$0.isSelected}.map{$0.name}
To load and save the names to UserDefaults add these two methods
func saveSelection()
{
let selectedAreaNames = areas.filter{$0.isSelected}.map{$0.name}
UserDefaults.standard.set(selectedAreaNames, forKey: "selectedNames")
}
func loadSelection()
{
guard let selectedAreaNames = UserDefaults.standard.array(forKey: "selectedNames") as? [String] else { return }
for (index, area) in areas.enumerated() {
areas[index].isSelected = selectedAreaNames.contains(area.name)
}
tableView.reloadData()
}

UITableView Multi Selection's selected checkmark not remains checked

I have two UITableView in my application.
One is for Category and Second is for SubCategory.
On the basis of selected Category SubCategory UITableView, data will change, and SubCategory UITableView have multi-selection functionality, till this my application is working fine.
Now the problem is when I am on category UITableView and click on suppose Category cell it will redirect to the various subCategory, On that screen, I have selected multiple choices and click on back button appear on top, and when I click again on Category tab my selection(Checkmark) is disappearing.
I want my checkmark to be selected as long as I manually set them as unchecked.
How can I implement that thing?
Sample screenshot of my application attached below.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tblSubCategory.cellForRow(at: indexPath)
if cell!.isSelected
{
cell!.isSelected = false
if cell!.accessoryType == UITableViewCell.AccessoryType.none
{
if strCategoryData == "Category" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedCetegoryIndex.append(objectForCell)
let defaults = UserDefaults.standard
defaults.set(arrSelectedCetegoryIndex, forKey: "categoryKey")
}
else if strCategoryData == "Brand" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedBrandIndex.append(objectForCell)
}
else if strCategoryData == "Color" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedColorIndex.append(objectForCell)
}
else if strCategoryData == "Size" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedSizeIndex.append(objectForCell)
}
}
else
{
if strCategoryData == "Category" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedCetegoryIndex.firstIndex(of: selectedIndexValue)!
arrSelectedCetegoryIndex.remove(at: index)
}
else if strCategoryData == "Brand" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedBrandIndex.firstIndex(of: selectedIndexValue)!
arrSelectedBrandIndex.remove(at: index)
}
else if strCategoryData == "Color" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedColorIndex.firstIndex(of: selectedIndexValue)!
arrSelectedColorIndex.remove(at: index)
}
else if strCategoryData == "Size" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedSizeIndex.firstIndex(of: selectedIndexValue)!
arrSelectedSizeIndex.remove(at: index)
}
}
}
}
You are probably performing a segue to go to the sub category view controller, and every time you perform this segue, tableview delegate and datasource methods are called again and cells are initialized all over again.
For you to show your cells checked you are going to need to save the checked values in the Categories view controller and pass them to the SubCategory View Controller and set the checked values in your cellForRowAtIndexpath method.
Here is an example on how to implement that:
class CategoryViewController: UIViewController {
var checkedValues = [[Bool]]()
var indexSelected = -1
override func viewDidLoad() {
super.viewDidLoad()
// your code here
checkedValues.append(contentsOf: repeatElement([], count: yourCategArray.count))
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// your code here
indexSelected = indexPath.row
self.performSegue(withIdentifier: "yourSegueIdentifierHere", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
(segue.destination as! SubCategoryViewController).parentCategoryVC = self
}
}
Now for the other View Controller:
class SubCategoryViewController: UIViewController {
var parentCategoryVC = CategoryViewController()
override func viewDidLoad() {
super.viewDidLoad()
if parentCategoryVC.checkedValues[parentCategoryVC.indexSelected].count == 0 {
parentCategoryVC.checkedValues[parentCategoryVC.indexSelected].append(contentsOf: repeatElement(false, count: yourSubCategArray.count))
}
// your code here
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourSubCategArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell...
if parentCategoryVC.checkedValues[parentCategoryVC.indexSelected][indexPath.row] { cell.accessoryType = .checkmark } else { cell.accessoryType = .none }
// your code here
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// your code
parentCategoryVC.checkedValues[parentCategoryVC.indexSelected][indexPath.row] = !parentCategoryVC.checkedValues[parentCategoryVC.indexSelected][indexPath.row]
tableView.reloadRows(at: indexPath, with: UITableViewRowAnimation.none)
}
}
For any additional clarification feel free to ask
You need to create one Int type array and then append value on click if not in array and if already exist so you need to remove from array and set checkmark in cellForRowAt method.
Please See complete code
import UIKit
class testViewController: UIViewController {
var selectedRows: [Int] = []
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension testViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "Welcome " + (indexPath.row+1).description
cell.selectionStyle = .none
cell.accessoryType = selectedRows.contains(indexPath.row) ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if self.selectedRows.contains(indexPath.row) {
if let index = self.selectedRows.firstIndex(of: indexPath.row) {
self.selectedRows.remove(at: index)
}
} else {
self.selectedRows.append(indexPath.row)
}
tableView.reloadData()
}
}

how to set the selected check mark as ticked in tableview cell swift 3.0

I am using one UITableView to select the country with tick mark. But when I move to other screen and when I come back my check mark is invisible. It seems like the country what I am selecting is fine, But after I move to other screen an come back, The selected tick mark is not there. How to do that in swift.
my code :
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var saveBtn: UIButton!
var languageName : String = String()
var option : [String] = ["English","हिंदी"]
var option1 : [String] = []
let availableLanguages = Localize.availableLanguages()
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
for language in availableLanguages {
option1.append(language)
let displayName = Localize.displayNameForLanguage(language)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
//MARK: - TableView
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return option1.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = option[indexPath.row]
if option1[indexPath.row] == languageName{
cell.accessoryType = UITableViewCellAccessoryType.checkmark
}else{
cell.accessoryType = UITableViewCellAccessoryType.none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
languageName = option1[indexPath.row]
self.tableView.reloadData()
}
#IBAction func saveButtonPressed(_ sender: Any) {
Localize.setCurrentLanguage(languageName)
if let appdelegate = UIApplication.shared.delegate as? AppDelegate {
appdelegate.showHomeLandingScreen()
}
}
1) create another array of selected items and save it there are so many options eg. UserDefaults.standard
2) then compare with option1[indexPath.row]
example
UserDefaults.standard.set(selectedLanguageArray, forKey: "selectedLanguageArray")
UserDefaults.standard.synchronize()
Then get it by
UserDefaults.standard.value(forKey: "selectedLanguageArray")
create another array of selected items
here option1[indexPath.row] compare this element with all element of another array
Here you go:-
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var saveBtn: UIButton!
var languageName : String = String()
var option : [String] = ["English","हिंदी"]
var selectedlang: [String] = []
let availableLanguages = Localize.availableLanguages()
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
for language in availableLanguages {
option1.append(language)
let displayName = Localize.displayNameForLanguage(language)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
//MARK: - TableView
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return option1.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = option[indexPath.row]
for (index,element) in selectedlang.enumerated(){
if element == option[indexPath.row]{
cell.accessoryType = UITableViewCellAccessoryType.checkmark
}else{
cell.accessoryType = UITableViewCellAccessoryType.none
}
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
languageName = option1[indexPath.row]
for (index,element) in newArr.enumerated(){
if element == languageName{
selectedlang.remove(at: index)
}else{
selectedlang.append(languageName)
}
}
self.tableView.reloadData()
}
#IBAction func saveButtonPressed(_ sender: Any) {
Localize.setCurrentLanguage(languageName)
if let appdelegate = UIApplication.shared.delegate as? AppDelegate {
appdelegate.showHomeLandingScreen()
}
}
}
Please use below code which i corrected and tested, It stores last changed language and will get it even when you move other screen an come back
// ViewController.swift
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var saveBtn: UIButton!
var languageName : String?
var option : [String] = ["English","हिंदी","French","Dutch"] //Your languages displays in table view
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
languageName = UserDefaults.standard.value(forKey: "MyselectedLanguage") as? String //Your last selected language fetch
self.tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
//MARK: - TableView
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return option.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = option[indexPath.row]
if option[indexPath.row] == languageName{
cell.accessoryType = UITableViewCellAccessoryType.checkmark
}else{
cell.accessoryType = UITableViewCellAccessoryType.none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
languageName = option[indexPath.row]
self.tableView.reloadData()
}
#IBAction func saveButtonPressed(_ sender: Any) {
UserDefaults.standard.set(languageName, forKey: "MyselectedLanguage")
UserDefaults.standard.synchronize()
if let appdelegate = UIApplication.shared.delegate as? AppDelegate {
appdelegate.showHomeLandingScreen()
}
}
}
See the reference Image:
Here is a similar code that I use to save News category selections, should help you with your problem.
Saves multiple values that are checked.
class ViewController {
var selectedCategoriesArray = [Any]()
private var appSettings: UserDefaults?
override func viewDidLoad() {
super.viewDidLoad()
appSettings = UserDefaults.standard
loadNewsSelectedCategories()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "cellNewsCategory", for: indexPath)
// Configure the cell...
cell?.textLabel?.text = "\(newsCategoriesArray[indexPath.row])"
let cellText: String? = cell?.textLabel?.text
for lbl: String in selectedNewsCategories {
if (cellText == lbl) {
cell?.accessoryType = .checkmark
break
}
else {
cell?.accessoryType = []
}
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let selectedCell: UITableViewCell? = tableView.cellForRow(at: indexPath)
let selectedCategory: String? = selectedCell?.textLabel?.text
if tableView.cellForRow(at: indexPath)?.accessoryType == [] {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
print("\(selectedCategory)")
selectedCategoriesArray += selectedNewsCategories
selectedCategoriesArray.append(selectedCategory)
let categories: [Any] = NSOrderedSet(selectedCategoriesArray).array()
print("+categories:\n \(categories)")
appSettings["selectedNewsCategories"] = categories
}
else if tableView.cellForRow(at: indexPath)?.accessoryType == .checkmark {
tableView.cellForRow(at: indexPath)?.accessoryType = []
print("\(selectedCategory)")
loadNewsSelectedCategories()
selectedCategoriesArray += selectedNewsCategories
selectedCategoriesArray.remove(at: selectedCategoriesArray.index(of: selectedCategory)!)
var categories: [Any] = NSOrderedSet(selectedCategoriesArray).array()
print("-categories:\n \(categories)")
appSettings["selectedNewsCategories"] = categories
}
else {
tableView.cellForRow(at: indexPath)?.accessoryType = []
}
appSettings.synchronize()
}
func loadNewsSelectedCategories() {
selectedNewsCategories = [Any]()
selectedNewsCategories = appSettings["selectedNewsCategories"]
}

Resources