I have a cell in (Table View List) of animals and i want to get from class of informations about the animals, what I want to do is get the name of the animal and put it in the cell.
This is ViewController class
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var TableViewList: UITableView!
var NotKiller = Array<Animal>()
var Killer = Array<Animal>()
var Sections = ["NotKiller", "Killer"]
override func viewDidLoad() {
super.viewDidLoad()
loadAnimals()
}
#IBAction func buAllAnimals(_ sender: Any) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return NotKiller.count
} else {
return Killer.count
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return Sections.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return Sections[section]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if indexPath.section==0 {
cell.textLabel?.text = "" //here where I want to add the name
} else {
cell.textLabel?.text = "" // here where I want to add the name
}
return cell
}
func loadAnimals(){
//here where I add the Items in to arrays
}
}
This is the Animal class
import Foundation
class Animal {
var Killing:String?
var Name:String?
var Des:String?
var Image:String?
init(Killing:String, Name:String, Des:String, Image:String) {
self.Killing = Killing
self.Name = Name
self.Des = Des
self.Image = Image
}
}
This would do it
if indexPath.section==0 {
cell.textLabel?.text = NotKiller[indexPath.row].Name
} else {
cell.textLabel?.text = Killer[indexPath.row].Name
}
As a side note, your variable names should start with a lowercase letter to easily tell them apart from type name. Killer looks like it's a type but it's really a variable.
Try this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if indexPath.section==0 {
cell.textLabel?.text = NotKiller[indexPath.row].name
} else {
cell.textLabel?.text = Killer[indexPath.row].name
}
return cell
}
Related
I have stuck up with an issue where I have a UITableView with a label and button in each row when the button is clicked from a particular row it will navigate to the next view and it has UITableView with a country list, when selected the country it will popup to the previous view and I want to update the country name with selected row, Could someone guide me how to update it. Below is my code. TIA
FirstViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableCell
let dict = customData[indexPath.row] as? NSObject
cell.lblTitle.text = "Title"
// cell.lblSubTitle.text = ""
cell.selectedButton.tag = indexPath.row
cell.selectedButton.addTarget(self, action: #selector(buttonClick), for: .touchUpInside)
return cell
}
#objc func buttonClick(sender: UIButton){
let customCell = CountryViewController(nibName: nil, bundle: nil)
self.navigationController?.pushViewController(customCell, animated: true)
}
CountryViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CountryCell", for: indexPath) as! CountryTableCell
cell.lblTitle.text = CountryList[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCountry = CountryList[indexPath.row]
self.navigationController?.popViewController(animated: true)
}
You can use delegation pattern:
protocol SelectCountry {
func countrySelected(withName countryName: String)
}
in your FirstViewController.swift conform to that protocol
extension FirstViewController: SelectCountry {
func countrySelected(withName countryName: String) {
// Assign country name to your label here
}
in your CountryViewController.swift make a variable called delegate/anyName you want
var delegate: SelectCountry?
in your buttonClick method
customCell.delegate = self
in your CountryViewController in didSelectRowAt method
delegate?.countrySelected(withName: CountryList[indexPath.row])
your label will be updated with country name you selected in CountryViewController.
NOTE: Names are just placeholders here you can use your own names for protocol/methods
First Controller:
"CountrySelectionDelegate" confirm this delegate in your first controller
Next, Pass/Store your FirstViewController cell selection index.
Go to your Country Controller, Select country, Pass it through "func selectedCountry(country: String,index: Int) {}" , Update your custom Data/Array.
Lastly reload your Table view with updated Custom data.
class FirstViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,CountrySelectionDelegate {
#IBOutlet weak var yourFirstTable: UITableView!
var customData = [Details(title: "Title-1", country: ""),Details(title: "Title - 2", country: ""),]
override func viewDidLoad() {
super.viewDidLoad()
}
func selectedCountry(country: String,index: Int) {
self.customData[index].country = country
yourFirstTable.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return customData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DetailTableCell
let custInfo = customData[indexPath.row]
cell.yourTitleLabel.text = "Title: " + custInfo.title
cell.yourCountryLabel.text = (custInfo.country.count > 0 ? "Country: \(custInfo.country)" : "Country: ---")
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "CountryViewController") as? CountryViewController
nextVC?.selectedIndex = indexPath.row
nextVC?.delegate = self
self.navigationController?.pushViewController(nextVC!, animated: true)
}
}
CountryViewController:
import UIKit
protocol CountrySelectionDelegate {
func selectedCountry(country: String, index:Int)
}
class CountryViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var countryTable: UITableView!
var selectedIndex: Int = 0
let countryList = ["India","USA","UK","Nepal","Bangladesh","Pakistan","Bhutan"]
weak var delegate: CountrySelectionDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return countryList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CountryTableViewCell
cell.countryLabel.text = countryList[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate?.selectedCountry(country: countryList[indexPath.row], index: selectedIndex)
self.navigationController?.popViewController(animated: true)
}
}
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.
Right now I am trying to move information from my goal cell into a new table view cell, and am having difficulty getting the cell to display.
Here is the code for my goal cell.
import UIKit
class GoalsViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var Goals: [String] = ["goal 1", "goal 2", "goal 3"]
let theEmptyModel: [String] = ["No data in this section."]
var valueToPass = ""
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func showGoalSelected() {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
let popUp = GoalSelectedPopUp()
self.view.addSubview(popUp)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "GoalConversationsCell_1") {
let viewController = segue.destination as! ActiveGoalsViewController
viewController.Goals.append([valueToPass])
}
}
}
extension GoalsViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Goals.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "GoalCell_1", for: indexPath)
cell.textLabel?.text = Goals[indexPath.row]
cell.textLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
cell.textLabel?.numberOfLines = 3
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
valueToPass = Goals[indexPath.row]
performSegue(withIdentifier: "activeGoalsSegue", sender: self)
Goals.remove(at: indexPath.row)
if Goals.count != 0 {
showGoalSelected()
} else {
Goals.append(contentsOf: theEmptyModel)
}
tableView.reloadData()
}
}
Here is the goal cells storyboard with the push segue connecting it to the other table view.
That other table view is shown below.
Here is the code for this new tableview.
import UIKit
class ActiveGoalsViewController: UIViewController {
#IBOutlet weak var goalTableView: UITableView!
let sections: [String] = ["Mark as Complete:", "History:"]
var goals: [[String]] = [[], []]
let theEmptyModel: [String] = ["No data in this section."]
extension ActiveGoalsViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Goals[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TodayGoalViewCell_1", for: indexPath) as? GoalTableViewCell
cell?.goalLabel.text = Goals[indexPath.section][indexPath.row]
cell?.cellDelegate = self
cell?.index = indexPath
return cell!
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return Goals.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
if Goals[0] != theEmptyModel {
Goals[1].append(Goals[0][indexPath.row])
if Goals[1].first!.contains("No data in this section.") {
Goals[1].removeFirst()
}
Goals[0].remove(at: indexPath.row)
if Goals[0].count == 0 {
Goals[0].append(contentsOf: theEmptyModel)
}
tableView.reloadData()
}
}
}
Once the goal is selected, it sends me to the new storyboard, but this new view does not display the goal that was just added. Can someone help me figure out why this isn't working? Thanks.
I think in the second view controller you need to access the "goals" variable with a lower case g rather then the "Goals" variable with an upper case G.
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
}
}
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"]
}