How to calculate values that are selected from xcode tableView - ios

i would like to make something like shopping, whenever the user selects a cell from the UITableView the price of that item will show in the total Label and when he selects another item the sum of the 2 items will show in the total label. i made a plist and store the items there. what i want to do now is how to assign the price values into the items and when the user selects a cell "item" the price will be shown. this is what i have made so far. please help me.
this is the view controller:
(https://imgur.com/sQnz1YY)
import UIKit
class ServiceListViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tablelbl: UITableView!
var SerArr :[ServiceOB] = []
var ArrService: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tablelbl.delegate = self
tablelbl.dataSource = self
let path = Bundle.main.path(forResource: "ServiceList", ofType: "plist")
let serArray : NSArray = NSArray(contentsOfFile: path!)!
for service in serArray {
print(service)
let serviceOBJ = ServiceOB()
// i change your plist to array
serviceOBJ.Service = service as! String
// check now..
SerArr.append(serviceOBJ)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return SerArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tablelbl.dequeueReusableCell(withIdentifier: "ServiceListCell") as! ServiceTableViewCell
let obj = SerArr[indexPath.row]
cell.servicelbl.text! = obj.Service
return cell
}
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
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.0
}
}

Create a delegate of tablecell and call delegate method from button click in tablecell.
protocol tableCellDelegate {
func callMethod()
}
class tableCell: UITableViewCell{
var delegate: tableCellDelegate?
#IBAction func selecteItem(_ sender: Any) {
delegate?.callMethod()
}
class VC: UIViewController{
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = .....
cell.delegate = self
return cell
}
func callMethod(){
// Do some thing}
}

It's easy. Just fetch the table cell with the original cell type that was used and keep a variable to store the value for total price:
#IBOutlet weak var priceLabel: UILabel!
var price: Double = 0.0 {
didSet {
// You can use localisation to change the currency. But that is currently not a part of the problem statement.
priceLabel?.text = "$\(price)"
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? ServiceTableViewCell {
// Assuming cell has a property for storing price: itemPrice
if cell.accessoryType == .checkmark {
totalPrice -= cell.itemPrice
cell.accessoryType = .none
} else {
totalPrice += cell.itemPrice
cell.accessoryType = .checkmark
}
}
}
NOTE: You don't need plist file for storing the selected values. But if you need it for some of the other reasons not mentioned here, you can alter the contents of the plist based on selection as well.

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
}
}

Swift Tableview checkmark disappeared after relaunch viewcontroller

In my case, I am loading JSON data into tableview. Here, the tableview cell multiple cell selection checkmark and uncheckmark options implemented. If go previous viewcontroller and comeback again tableview controller then last selected checkmark disappeared. How to store it?
JSON Codable
// MARK: - Welcome
struct Root: Codable {
let status: Bool
let data: [Datum]
}
// MARK: - Datum
struct Datum: Codable, Hashable {
let userid, firstname, designation: String?
let profileimage: String?
}
Custom Cell Class
class MyCustomCell: UITableViewCell {
#IBOutlet weak var profileImage: UIImageView!
#IBOutlet weak var nameCellLabel: UILabel!
#IBOutlet weak var subtitleCellLabel: UILabel!
}
Code for Tableview Checkmark
var studentsData = [Datum]()
var sessionData = Set<Datum>()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:MyCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MyCustomCell
let item = self.studentsData[indexPath.row]
cell.nameCellLabel.text = item.firstname
cell.subtitleCellLabel.text = item.designation
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let item = self.studentsData[indexPath.row]
if let cell = tableView.cellForRow(at: indexPath) {
if cell.accessoryType == .checkmark {
cell.accessoryType = .none
// UnCheckmark cell JSON data Remove from array
self.sessionData.remove(item)
print(sessionData)
} else {
cell.accessoryType = .checkmark
// Checkmark selected data Insert into array
self.sessionData.insert(item)
print(sessionData)
}
}
}
Create a means to store the checkmark status within your data struct
struct Datum: Codable, Hashable {
let userid, firstname, designation: String?
let profileimage: String?
var selected: Bool = false
}
Set the value when you create a cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:MyCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MyCustomCell
let item = self.studentsData[indexPath.row]
cell.nameCellLabel.text = item.firstname
cell.subtitleCellLabel.text = item.designation
cell.accessoryType = item.selected ? .checkmark : .none
return cell
}
And then in the didSelectRowAt replace the if block with the below to save the change back to the student data and then reset the checkmark accordingly:
self.studentsData[indexPath.row].selected.toggle()
cell.accessoryType = studentsData[indexPath.row].selected ? .checkmark : .none
You should always save the checkMark status in another array or variable.
In case only one item can be selected:
var SELECTED_ITEMS= [YOUR_DATA_TYPE]()//It must be global within tableViewController
in case multiple selection allowed
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let item = self.studentsData[indexPath.row]
if SELECTED_ITEMS.contain(item){
SELECTED_ITEMS.remove(item)
}else{
SELECTED_ITEMS.append(item)
}
}
Remember SELECTED_ITEM should be Array of your tableviewdata and SELECTED_ITEM is just the same type of your tableview data.
Also if you are initializing your model in ViewDidLoad or ViewWillAppear in tableview controller, make should SELECTED_ITEMS and SELECTED_ITEM are not reset when tableview appears.
then
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
........
cell.accessoryView = SELECTED_ITEMS.contain(item) ? .checkmark:.none// Multi Selection
.........
}
In general, you update your model, a variable or array or whatever fits in your code to keep a track of which indexpath is select/unselected. Then in cellForRowAt you can check the above variable/array... to set accessory.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath){}
will also work

how to make limited multiple checkmark in Table View Cell in Swift?

I am new in programming and iOS Development, I need to make table view that has multiple limited checkmark.
I mean, I want to allow the user to select maximum 3 items (not just 1, but also not all of item in the table view can be selected) in the table view, I have tried but I haven't gotten what I want, I just can select one only item in table view
here is the code I use
import UIKit
class CreateEventStep2VC: UIViewController {
#IBOutlet weak var eventTypeNameLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
var newEvent : [String:Any]!
var eventTypeAvailableData = [String]()
var selectedEventTypes = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// initial value
eventTypeNameLabel.text = ""
// get event Type Data list from EventType data model
eventTypeAvailableData = EventType.allValues.map { $0.toString() }
}
}
extension CreateEventStep2VC : UITableViewDataSource {
//MARK: - UITableViewDatasource
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return eventTypeAvailableData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "EventTypeCell", for: indexPath) as! CreateEventStep2Cell
cell.eventTypeNames = eventTypeAvailableData[indexPath.row]
return cell
}
}
extension CreateEventStep2VC : UITableViewDelegate {
//MARK: - UITableViewDelegate
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
}
}
could you please help me ?
You can't simply add the checkmark to the cell; cell objects will be re-used as the tableview scrolls, so you will lose checkmarks and end up with checkmarks in cells that shouldn't have them.
You need to track the checked cells in another structure; I suggest using a Set<IndexPath>. You can either allow multi-selection in your tableview, or (my preference) deselect the row after you add the checkmark.
You also need to ensure that your cellForRowAt: sets the accessory type correctly
class CreateEventStep2VC: UIViewController {
#IBOutlet weak var eventTypeNameLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
var newEvent : [String:Any]!
var eventTypeAvailableData = [String]()
var selectedEventTypes = Set<IndexPath>()
override func viewDidLoad() {
super.viewDidLoad()
// initial value
eventTypeNameLabel.text = ""
// get event Type Data list from EventType data model
eventTypeAvailableData = EventType.allValues.map { $0.toString() }
}
}
extension CreateEventStep2VC : UITableViewDataSource {
//MARK: - UITableViewDatasource
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return eventTypeAvailableData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "EventTypeCell", for: indexPath) as! CreateEventStep2Cell
cell.eventTypeNames = eventTypeAvailableData[indexPath.row]
cell.accessoryType = selectedEventTypes.contains(indexPath) ? .checkMark:.none
return cell
}
}
extension CreateEventStep2VC : UITableViewDelegate {
//MARK: - UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
if selectedEventTypes.contains(indexPath) {
selectedEventTypes.remove(indexPath)
} else if selectedEventTypes.count < 3 {
selectedEventTypes.insert(indexPath)
}
tableView.reloadRows(at: [indexPath], animated:.none)
}
}
You can have array of indexPath rows allArr like this
1- when user selects more than 3 the first one will be automatically dropped
var allArr = [Int]()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
allArr.append(indexPath.row)
}
if(allArr.count == 4)
{
allArr.dropFirst()
}
}
2- add this to cellForRow
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "EventTypeCell", for: indexPath) as! CreateEventStep2Cell
cell.eventTypeNames = eventTypeAvailableData[indexPath.row]
if allArr.contains(indexPath.row) {
cell.accessoryType = .checkmark
}
else
{
cell.accessoryType = .none
}
return cell
}
3- remove code in didSelectRowAt

How i can fill two different tableview in one viewcontroller in swift 3

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == table1{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! acntTableViewCell
cell.account.text = account[indexPath.row].email
return cell
}
else if tableView == table2 {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "cell2")
as! popTableViewCell
cell2.pop.text = pop[indexPath.row].answer
return cell2
}
}//its give me error here Missing return in function
I am going to fill two different tables in one viewcontroller. when I return cell it give me error Missing return in function where I am doing wrong can any one suggest me what's wrong with this code
In the first place, you should compare tables using === (references), not ==.
This is one of the cases when an assertion failure is a good way to tell the compiler that no other way of the function exists e.g.:
if tableView === table1 {
return ...
} else if tableView === table2 {
return ...
} else {
fatalError("Invalid table")
}
You can also use a switch:
switch tableView {
case table1:
return ...
case table2:
return ...
default:
fatalError("Invalid table")
}
Both answers are correct, but I believe the best way to do it would be to separate each table view to have its own data source object, not a view controller. Putting multiple tableview data source protocols adds a decent amount of unnecessary code, and if you refactor them into separate objects, you can help avoid a Massive View Controller.
class FirstTableViewDataSource : NSObject, UITableViewDataSource {
var accounts: [ObjectTypeHere]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return accounts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! AcntTableViewCell
cell.account.text = accounts[indexPath.row].email
return cell
}
}
class SecondTableViewDataSource : NSObject, UITableViewDataSource {
var pops: [ObjectTypeHere]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pops.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PopTableViewCell
cell.account.text = pops[indexPath.row].answer
return cell
}
}
From there, just update the tableviews to pull from these objects
override func viewDidLoad() {
super.viewDidLoad()
self.table1.dataSource = FirstTableViewDataSource()
self.table2.dataSource = SecondTableViewDataSource()
}
The compiler is analyzing what will happen if tableView is neither table1 nor table2. If that should happen, the function will exit with nothing to return.
That's an error.
Your cellForRowAt method should always return a cell, so
Try this way
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == table1{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! acntTableViewCell
cell.account.text = account[indexPath.row].email
return cell
}
//if tableView is not table1 then
let cell2 = tableView.dequeueReusableCell(withIdentifier: "cell2")
as! popTableViewCell
cell2.pop.text = pop[indexPath.row].answer
return cell2
}
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var table1: UITableView!
#IBOutlet weak var table2: UITableView!
let firstClassRef = FirstTableView()
let secondClassRef = SecondTableView()
override func viewDidLoad() {
super.viewDidLoad()
firstClassRef.array1 = ["1","2","3"]
secondClassRef.array2 = ["1","2","3","1","2","3"]
self.table1.dataSource = firstClassRef
self.table2.dataSource = secondClassRef
self.table1.delegate = firstClassRef
self.table2.delegate = secondClassRef
self.table1.reloadData()
self.table2.reloadData()
}
}
class FirstTableView: NSObject, UITableViewDataSource, UITableViewDelegate {
var array1 = Array<Any>()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return array1.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as UITableViewCell
cell.textLabel?.text = array1[indexPath.row] as? String
cell.backgroundColor = UIColor.yellow
return cell
}
}
class SecondTableView: NSObject, UITableViewDataSource, UITableViewDelegate {
var array2 = Array<Any>()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return array2.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as UITableViewCell
cell.textLabel?.text = array2[indexPath.row] as? String
cell.backgroundColor = UIColor.yellow
return cell
}
}
Use Switch Statement
import UIKit
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {
#IBOutlet weak var topTableView: UITableView!
#IBOutlet weak var downTableview: UITableView!
var topData : [String] = []
var downData = [String]()
override func viewDidLoad() {
super.viewDidLoad()
topTableView.delegate = self
downTableview.delegate = self
topTableView.dataSource = self
downTableview.dataSource = self
for index in 0...20 {
topData.append("Top Table Row \(index)")
}
for index in 10...45 {
downData.append("Down Table Row \(index)")
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var numberOfRow = 1
switch tableView {
case topTableView:
numberOfRow = topData.count
case downTableview:
numberOfRow = downData.count
default:
print("Some things Wrong!!")
}
return numberOfRow
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
switch tableView {
case topTableView:
cell = tableView.dequeueReusableCell(withIdentifier: "topCell", for: indexPath)
cell.textLabel?.text = topData[indexPath.row]
cell.backgroundColor = UIColor.green
case downTableview:
cell = tableView.dequeueReusableCell(withIdentifier: "downCell", for: indexPath)
cell.textLabel?.text = downData[indexPath.row]
cell.backgroundColor = UIColor.yellow
default:
print("Some things Wrong!!")
}
return cell
}
}

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