How to add multiple items to a UITableViewCell? - swift

Can anyone help me get the email field to display in the tableView cell? The amount field is showing up, but I can't get the email to show along with it.
struct Posts {
var amount:String
var email:String
}
class PaymentRequestVC: UIViewController, UITableViewDelegate {
let tableView = UITableView()
var posts = [Posts]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.tableView.dataSource = self
self.tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell2")
tableView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 900)
setupViews()
setupTableView()
loadPosts()
self.tableView.reloadData()
}
func loadPosts() {
let dbUsers = Firestore.firestore().collection("Payouts")
dbUsers.addSnapshotListener { (querySnapshot, error) in
if let error = error {
print("\(error.localizedDescription)")
} else {
for document in (querySnapshot?.documents)! {
if let Amount = document.data()["amount"] as? String {
let Email = document.data()["email"] as? String
print(Amount)
var post = Posts(amount: "", email: "")
post.amount = Amount
post.email = Email ?? ""
self.posts.append(post)
}
}
self.tableView.reloadData()
print(self.posts)
}
}
}
private func setupViews() {
let stackView: UIStackView = {
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.spacing = 28
sv.axis = .vertical
sv.distribution = .fill
sv.alignment = .fill
return sv
}()
view.addSubview(stackView)
view.addSubview(tableView)
}
func setupTableView() {
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: self.view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor)
])
}
}
extension PaymentRequestVC: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath)
let post = posts[indexPath.row]
cell2.detailTextLabel?.text = post.email
cell2.detailTextLabel?.textColor = UIColor.black
return cell2
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
}

Swift 5
You need to init the cell with UITableViewCell.CellStyle.subtitle for the detailTextLabel attribute to work.
In your extension, change the cell init:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.text = post.email
cell.detailTextLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell2")
let post = posts[indexPath.row]
cell2.detailTextLabel?.text = post.email
cell2.detailTextLabel?.textColor = UIColor.black
return cell2
}
Note that if you want the amount and the mail to both show up, using else will only display either the amount or the email, like in the code below
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell2")
let post = posts[indexPath.row]
cell2.detailTextLabel?.text = post.email
cell2.detailTextLabel?.textColor = UIColor.black
return cell2
}
So a better approach would be to return both, and else display nothing
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.text = post.email
cell.detailTextLabel?.textColor = UIColor.black
return cell
} else {
let cell2 = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell2")
//Empty cell returned if the condition above is not fulfilled
return cell2
}
Hope this helps.

I think your logic in cellForRowAt is incorrect.
You have an array of Posts. And you want to display amount and email in the same cell right? One label being the title and the other being the detailed text.
Both labels are in the same UITableViewCell, so you only need to set it up once per post.
In addition, if indexPath.row is greater than the post count, then posts[indexPath.row] would actually crash your code. So that else statement should actually just log an error or simply do nothing.
Try something like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < posts.count {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let post = posts[indexPath.row]
cell.textLabel?.text = post.amount
cell.textLabel?.textColor = UIColor.black
cell.textLabel?.detailTextLabel?.text = post.email
cell.textLabel?.detailTextLabel?.textColor = UIColor.black
return cell
} else {
// No cells
}
}

Related

Getting id by clicking on tableView

By clicking on the red area I get a comment id. But I also want to get the id if I click on the blue button. How can I do that?
Right now I use this to detect a tap on a row. But tapping on button should run some other code.
extension FirstTabSecondViewComment: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
FirstTabSecondViewComment.subComment = table[indexPath.row].commentId ?? ""
print(FirstTabSecondViewComment.subComment)
self.performSegue(withIdentifier: "CommentDetail", sender: Any?.self)
}
}
After you have register your custom cell declare it in cellForRowAt and add target in button cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! MyCell // your custom cell
// add target in buoon cell
cell.YourButtonCell.addTarget(self, action: #selector(submit(_:)), for: .touchUpInside)
return cell
}
after that add submit func:
#objc fileprivate func submit(_ sender: UIButton) {
var superview = sender.superview
while let view = superview, !(view is UITableViewCell) {
superview = view.superview
}
guard let cell = superview as? UITableViewCell else {
print("button is not contained in a table view cell")
return
}
guard let indexPath = tableView.indexPath(for: cell) else {
print("failed to get index path for cell containing button")
return
}
// We've got the index path for the cell that contains the button, now do something with it.
print("button is in index \(indexPath.row)")
}
This is a full code example, copy and paste in a new project and run:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.register(MyCell.self, forCellReuseIdentifier: cellId)
}
#objc fileprivate func submit(_ sender: UIButton) {
var superview = sender.superview
while let view = superview, !(view is UITableViewCell) {
superview = view.superview
}
guard let cell = superview as? UITableViewCell else {
print("button is not contained in a table view cell")
return
}
guard let indexPath = tableView.indexPath(for: cell) else {
print("failed to get index path for cell containing button")
return
}
// We've got the index path for the cell that contains the button, now do something with it.
print("button is in index \(indexPath.row)")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyCell
// add target in buoon cell
cell.cancelButton.addTarget(self, action: #selector(submit(_:)), for: .touchUpInside)
return cell
}
}
class MyCell: UITableViewCell {
let cancelButton: UIButton = {
let b = UIButton(type: .system)
b.backgroundColor = .white
b.setTitle("get Index", for: .normal)
b.layer.cornerRadius = 10
b.clipsToBounds = true
b.titleLabel?.font = .systemFont(ofSize: 16, weight: .semibold)
b.tintColor = .black
b.translatesAutoresizingMaskIntoConstraints = false
return b
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .darkGray
contentView.addSubview(cancelButton)
cancelButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
cancelButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
cancelButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
cancelButton.widthAnchor.constraint(equalToConstant: 300).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

UITableViewCell textLabel not covering the full width of the cell

I tried all the popular suggestions like:
tableView.cellLayoutMarginsFollowReadableWidth = false
tableView.contentInset = .zero
tableView.separatorInset = .zero
but still im getting some spacing between the textlabel and the parent cell like below:
Cell creation code is shown below:
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = eligibleArray[indexPath.row]
cell.layoutMargins = .zero
cell.separatorInset = .zero
cell.textLabel?.textColor = .secondaryLabel
cell.textLabel?.backgroundColor = .systemOrange
cell.textLabel?.numberOfLines = 0
cell.backgroundColor = .systemPink
Please help with suggestions
This is the max that you can do with default textLabel cell:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
if (cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins))) {
cell.preservesSuperviewLayoutMargins = false
}
if (cell.responds(to: #selector(setter: UIView.layoutMargins))) {
cell.layoutMargins = UIEdgeInsets.zero
}
if tableView.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
tableView.separatorInset = .zero
}
}
and this is the result
otherwise you can create a custom cell to have total control:
class YourController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(YourCell.self, forCellReuseIdentifier: "cellId")
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! YourCell
cell.myLabel.text = "System will compute elegibility based on the current LTV of the loanscheme selected"
cell.myLabel.numberOfLines = 0
cell.myLabel.backgroundColor = .orange
cell.backgroundColor = .systemPink
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
your cell:
class YourCell: UITableViewCell {
let myLabel: UILabel = {
let l = UILabel()
l.backgroundColor = .orange
l.textColor = .black
l.numberOfLines = 0
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(myLabel)
myLabel.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
myLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
myLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
myLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
and this is the result

“Thread 1: Fatal error: Index out of range in Swift” from TableView

I want to pull the data from chipnumber2 and chipnumber. I want to collect the two in a table, but there's a problem. How do I draw data from two text tables? "let deviceItem: Device3New = itemsNew[indexPath]".I'm getting this problem on the row. In short, I want to draw the data in Device3New and device3 to the same table. How can I do that?
class NewMainTableViewController: UITableViewController {
var items: [Device3] = []
var itemsNew: [Device3New] = []
let cellId: String = "cellId"
let cellIdNew: String = "cellIdNew"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(DeviceTableViewCell2.self, forCellReuseIdentifier: cellId)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if !chipnumber2.text!.isEmpty {
let cellNew = tableView.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3New = itemsNew[indexPath.row]
cellNew.badgeColor = UIColor.flatLime
cellNew.badgeTextColor = .white;
cellNew.badgeFontSize = 13;
cellNew.badgeString = deviceItem.time
cellNew.badgeOffset = CGPoint(x:30.0, y:63)
cellNew.textLabel?.text = deviceItem.title
cellNew.deviceItem3New = deviceItem
cellNew.titleNew.text = deviceItem.title
cellNew.title1New.text = deviceItem.places
cellNew.titlesaatNew.text = deviceItem.time
cellNew.buttonNew.isOn = deviceItem.state
cellNew.tablerow = String (indexPath.row)
cellNew.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cellNew
}
if !chipnumber.text!.isEmpty {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3 = items[indexPath.row]
cell.badgeColor = UIColor.flatLime
cell.badgeTextColor = .white;
cell.badgeFontSize = 13;
cell.badgeString = deviceItem.time
cell.badgeOffset = CGPoint(x:30.0, y:63)
cell.textLabel?.text = deviceItem.title
cell.deviceItem3 = deviceItem
cell.title.text = deviceItem.title
cell.title1.text = deviceItem.places
cell.titlesaat.text = deviceItem.time
cell.button.isOn = deviceItem.state
cell.tablerow = String (indexPath.row)
cell.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cell
}
return UITableViewCell()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !chipnumber2.text!.isEmpty {
return itemsNew.count + items.count
} else if !chipnumber.text!.isEmpty {
return items.count
}
return 0
}
The problem is that cellForRowAt it trying to handle a scenario where there are two arrays, but both deviceItem assignments are using the same indexPath.row as an index within the respective array. But if items has two items and newItems has three, the cellForRowAt will called five times, with indexPath.row values ranging between 0 through 4. But you’re using indexPath.row in both arrays, and so you’re going to go beyond the bounds of the array for one or both of items and newItems.
The easiest solution is to have two sections, one for items and another for newItems. That gets you out of the business of having to figure out which indexPath belongs to which array:
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return itemsNew.count
} else {
return items.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cellNew = tableView.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem = itemsNew[indexPath.row]
...
return cellNew
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem = items[indexPath.row]
...
return cell
}
}
Note, I’m not looking at the text fields. The above assumes that you’ll just populate both arrays (and call tableView.reloadData()).
it because you add items and ItemsNew for define the tableViewCell, you should use just one of them or use a protocol for sync them as well.
so here is the correct code
class NewMainTableViewController: UITableViewController {
var items: [Device3] = []
var itemsNew: [Device3New] = []
var sumItems: []
let cellId: String = "cellId"
let cellIdNew: String = "cellIdNew"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(DeviceTableViewCell2.self, forCellReuseIdentifier: cellId)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if !chipnumber2.text!.isEmpty {
let cellNew = tableView.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3New = itemsNew[indexPath.row]
cellNew.badgeColor = UIColor.flatLime
cellNew.badgeTextColor = .white;
cellNew.badgeFontSize = 13;
cellNew.badgeString = deviceItem.time
cellNew.badgeOffset = CGPoint(x:30.0, y:63)
cellNew.textLabel?.text = deviceItem.title
cellNew.deviceItem3New = deviceItem
cellNew.titleNew.text = deviceItem.title
cellNew.title1New.text = deviceItem.places
cellNew.titlesaatNew.text = deviceItem.time
cellNew.buttonNew.isOn = deviceItem.state
cellNew.tablerow = String (indexPath.row)
cellNew.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cellNew
}
if !chipnumber.text!.isEmpty {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3 = items[indexPath.row]
cell.badgeColor = UIColor.flatLime
cell.badgeTextColor = .white;
cell.badgeFontSize = 13;
cell.badgeString = deviceItem.time
cell.badgeOffset = CGPoint(x:30.0, y:63)
cell.textLabel?.text = deviceItem.title
cell.deviceItem3 = deviceItem
cell.title.text = deviceItem.title
cell.title1.text = deviceItem.places
cell.titlesaat.text = deviceItem.time
cell.button.isOn = deviceItem.state
cell.tablerow = String (indexPath.row)
cell.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cell
}
return UITableViewCell()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !chipnumber2.text!.isEmpty {
return itemsNew.count //+ items.count
} else if !chipnumber.text!.isEmpty {
return items.count
}
return 0
}

Maximum one checkmark in TableView in Swift

I would like that users can choose maximum one voice. And that the checkmark jumps to where you tapt and deselect the other.
It looks like very simple, but I don't see the solution. And I can't find the answer on the internet.
Please can anybody help me?
Thanks advance!
import UIKit
import AVFoundation
class voicesTableViewController: UITableViewController {
fileprivate let synthesizer = AVSpeechSynthesizer()
fileprivate var speechVoices = AVSpeechSynthesisVoice.speechVoices()
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return speechVoices.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
//Name
let voice = speechVoices[indexPath.row]
let voiceLang = voice.language as? String
let theVoice = UserDefaults.standard.object(forKey:"voice") as? String
cell.textLabel?.text = voice.name
// Language
if let language = countryName(countryCode: voice.language) {
cell.detailTextLabel?.text = "\(language)"
}
else {
cell.detailTextLabel?.text = ""
}
cell.detailTextLabel?.textColor = UIColor.gray
// Checkmark
if (theVoice != nil) {
if(theVoice == voiceLang) {
cell.accessoryType = UITableViewCellAccessoryType.checkmark
}
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let voice = speechVoices[indexPath.row]
if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCellAccessoryType.checkmark {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.none
}
else
{
//if ((tableView.indexPathsForSelectedRows?.count)! > 1) {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.checkmark
//}
}
UserDefaults.standard.set(voice.language, forKey:"voice")
UserDefaults.standard.synchronize()
tableView.deselectRow(at: indexPath, animated: true)
}
func countryName(countryCode: String) -> String? {
let preferredLanguage = NSLocale.preferredLanguages[0] as String
let current = Locale(identifier: preferredLanguage)
return current.localizedString(forLanguageCode: countryCode) ?? nil
//return current.localizedString(forIdentifier: indentifier) ? nil
}
}
Simple change of function cellForRow:atIndexPathshould work:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
//Name
let voice = speechVoices[indexPath.row]
let voiceLang = voice.language as? String
let theVoice = UserDefaults.standard.object(forKey:"voice") as? String
cell.textLabel?.text = voice.name
// Language
if let language = countryName(countryCode: voice.language) {
cell.detailTextLabel?.text = "\(language)"
}
else {
cell.detailTextLabel?.text = ""
}
cell.detailTextLabel?.textColor = UIColor.gray
// Checkmark
if(theVoice != nil && theVoice == voiceLang) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
UPD#1
But you can use better solution:
1) Add property fileprivate var selectedIndexPath: IndexPath?
2) Change function func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)to next one:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
//Name
let voice = speechVoices[indexPath.row]
let voiceLang = voice.language as? String
let theVoice = UserDefaults.standard.object(forKey:"voice") as? String
cell.textLabel?.text = voice.name
// Language
if let language = countryName(countryCode: voice.language) {
cell.detailTextLabel?.text = "\(language)"
}
else {
cell.detailTextLabel?.text = ""
}
cell.detailTextLabel?.textColor = UIColor.gray
// Checkmark
cell.accessoryType = self.selectedIndexPath == indexPath ? .checkmark : .none
return cell
}
3) And then in func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) you can do next:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let voice = speechVoices[indexPath.row]
self.selectedIndexPath = indexPath
UserDefaults.standard.set(voice.language, forKey:"voice")
UserDefaults.standard.synchronize()
tableView.deselectRow(at: indexPath, animated: true)
tableView.reloadRows(at: [indexPath], with: .automatic)
}

How to Set data to second tableview in same Class in swift

How to Set data to second tableview in same Class in swift.I am using two tables in the the same controller one for dropdown and another for listing. I am unable to set data to second table(listing) in class
as else part is not called in cellForRowAtIndexPath. Thanks in Advance
import UIKit
class PunchClockVC: UIViewController , UITableViewDataSource, UITableViewDelegate{
var appdel = UIApplication.sharedApplication().delegate as! AppDelegate
#IBOutlet weak var dropdownTable: UITableView!
#IBOutlet weak var mainTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.mainTable.registerClass(PunchClockCustomCell.self, forCellReuseIdentifier: "PunchClockCustomCell")
self.dropdownTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "dropdowncell")
self.dropdownTable.hidden = true
}
#IBAction func textFieldTapped(sender: AnyObject) {
if self.dropdownTable.hidden == true {
self.dropdownTable.hidden = false
}
else{
self.dropdownTable.hidden = false
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == dropdownTable {
return jobArrayID.count
}
return 8
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView == self.dropdownTable {
let cell = tableView.dequeueReusableCellWithIdentifier("dropdowncell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = (jobArrayID[indexPath.row] as! String) + "-" + (jobArrayName[indexPath.row] as! String)
return cell
}
else {
let cell1 = tableView.dequeueReusableCellWithIdentifier("PunchClockCustomCell", forIndexPath: indexPath) as! PunchClockCustomCell
if indexPath.row == 0
{
cell1.jobcell?.font = UIFont(name: "MuseoSlab-500", size: 25.0)
cell1.locationcell?.font = UIFont(name: "MuseoSlab-500", size: 25.0)
cell1.timecell?.font = UIFont(name: "MuseoSlab-500", size: 25.0)
cell1.typecell?.font = UIFont(name: "MuseoSlab-500", size: 25.0)
cell1.jobcell?.textColor = UIColor.blackColor()
cell1.locationcell?.textColor = UIColor.blackColor()
cell1.timecell?.textColor = UIColor.blackColor()
cell1.typecell?.textColor = UIColor.blackColor()
cell1.jobcell?.text = "Job"
cell1.locationcell?.text = "Location"
cell1.timecell?.text = "Time"
cell1.typecell?.text = "Type"
// return cell1
}
else {
cell1.jobcell?.text = "Jobdata"
cell1.locationcell?.text = "Locationdata"
cell1.timecell?.text = "Timedata"
cell1.typecell?.text = "OUT"
// return cell1
}
return cell1
}
}
It's quite simple You need to set it only with cellForRowAtIndexPath method but the main thing to do is you need to code like below
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
if tableView == firstTbaleView
//outlet given to first tableView
{
let cell = tableView.dequeueReusableCellWithReuseIdentifier("cell1", forIndexPath: indexPath) as! cust1TableViewCell
cell.imgView.image = images[indexPath.row]
cell.filtLabel.text = self.filtersCount[indexPath.row]
return cell
}}else {
let cell2 = tableView.dequeueReusableCellWithReuseIdentifier("cell2", forIndexPath: indexPath) as! cust2TableViewCell
cell2.imgview.image = UIImage(named: colPhotos[indexPath.row])
cell2.labl.text = colNames[indexPath.row]
// cell2.layer.borderColor = UIColor.blueColor().CGColor
// cell2.layer.borderWidth = 2.0
return cell2
}
and that's it you can ask me for any help..
Lets make this a little safer:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.dropdownTable {
return jobArray.count
}
else if tableView == self.mainTable {
return = 5
}
//Default return 0. This way if references are broken or change, you won't crash
return 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView == self.dropdownTable {
let cell = tableView.dequeueReusableCellWithIdentifier("dropdowncell", forIndexPath: indexPath) as! UITableViewCell
//configure your cell
return cell
}
else if tableView == self.mainTable {
let cell = tableView.dequeueReusableCellWithIdentifier("PunchClockCustomCell", forIndexPath: indexPath) as! PunchClockCustomCell
//configure your cell
return cell
}
//Shouln't ever reach here, but again, if we refactor somewhere then we'll see an error show up before here.
return UITableViewCell()
}