How to change the title of a Button in a TableView (Swift) - swift

I am trying to make a button when pressed to call a phone number. In the TableView the button's title is supposed to be changed with the contact dictionary I added
Here is the Button:
#IBAction func phoneLabel(sender: UIButton) {
let url:NSURL = NSURL(string: "tel://contacts.phone")!
UIApplication.shared.openURL(url as URL)
}
and this is the tableview where I'm trying to set the button tile to the contact phone numbers
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ContactCell", for: indexPath) as! customCell
let contact = contacts.contactWithIndex((indexPath as NSIndexPath).row)
print(contact)
cell.phoneLabel.setTitle("\(phone)", for:UIControlState)
return cell
}
There is an error occurring saying that the button has no value of setTitle. Any help would be awesome!

Assuming it's a button and not a label (looking at your sender definition), you must specify UIControlState.normal, not UIControlState.
https://developer.apple.com/reference/uikit/uicontrolstate/1618233-normal

Related

<Swift>How to navigate to a new page in custom cell?

I have a custom cell FeedCell.swift and the controller FeedViewController.swift. And I set a btn in each cell so that I can navigate to detailController.swift. But in custom cell I can't use self.navigation. What should I do?
You can set an outlet of Button in cell and addTarget it like :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! yourCell
cell.yourButton.addTarget(self, action: #selector(goDetail), for: .touchUpInside)
return cell
}
#objc func goDetail(){
let vc = // Declare your viewController
self.navigationController?.pushViewController(vc, animated:true)
}
Btw you can add this action when a cell selected instead of using button
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let vc = // Declare your viewController
self.navigationController?.pushViewController(vc, animated:true)
}
If you want to send which cell's button clicked just add cell.yourButton.tag = indexPath.row in cellForRowAt and modify goDetail with
#objc func goDetail(sender : UIButton){
sender.tag // while give your selected cell index
}

Trying to bind an output to my tableviewCell UI Element in RxSwift

I have an output that lives in my VM and based on some change I want my textfield that resides in my custom tableviewCell to change in some way. I am unsure about how to have my UItextfield that lives in the tableviewcell bind to my output.
let index = IndexPath(row: 0, section: 0)
if let cell = tbl.cellForRow(at: index) as? TableViewCell {
print(cell.textF.text)
// Do whatever you want
}
I am not sure when you want to get the data, but if you want to do this when the user touches the cell, just implement the following method of UITableViewDelegate:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? YourTableViewCellClass {
let cellLabelText = cell.yourTextField.text
// Do whatever you want with cellLabel
}
}

Swift tableview cell doesn't save the state with different identifier

I am very confused on the reuse of the cells.
I have a table, each cell is a cell with a switch on it. If I toggle a switch I set the background color of that cell to a different color. However every time I scroll these changes don't persist.
I am subclassing UITalbeViewCell to create my own custom cell. Each cell has a different identifier. However when I scroll through the table, whatever changes I made to the cell still doesn't save. I've read similar questions but none of them worked.. Some suggested subclass which I did, some suggested use different identifier which I also did...
Here is the code of my tableview.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let key = Array(dataSource[indexPath.section].keys)[indexPath.row]
let cell = CellWithSwitch.init(style: .subtitle, reuseIdentifier: key)
cell.awakeFromNib()
let val = Array(dataSource[indexPath.section].values)[indexPath.row]
cell.switchView?.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
if let index = key.firstIndex(of: "."){
cell.textLabel?.text = String(key.suffix(from: key.index(index, offsetBy: 1)))
}else{
cell.textLabel?.text = key;
}
cell.switchView?.setOn(val, animated: true)
return cell
}
You can change array value in switchChange action
lets i take array for switch as below:
var arrSwitch = [false,false,false,false,false,false,false,false,false,false]
Below is my cellForRowAt Method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! customCell
cell. switchView.setOn(self.arrSwitch[indexPath.row], animated: false)
cell. switchView.tag = indexPath.row
cell. switchView.addTarget(self, action: #selector(self.onSwitchTap(_:)), for: .valueChanged)
return cell
}
Here is my onSwitchTap Action
#IBAction func onSwitchTap(_ sender: UISwitch) {
self.arrSwitch[sender.tag] = !self.arrSwitch[sender.tag]
}
Now on scroll it will persist last changes you have done.

Swift - Making a Button for UITableViewCell with .addTarget

I'm trying to make two different buttons for each cell that I create in my table view. One of the buttons is a + button that will increment a label. In my testing however I cannot get the function to work. My current error says
Argument of #selector does not refer to an '#objc' method, property, or initializer
I feel like I'm implementing the .addTarget method completely wrong but I am new. Here is my code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as! AddItemCell
cell.setCell(item: item)
let itemAmount = cell.itemAmount as UILabel?
cell.addButton.addTarget(self, action: #selector(addItem(sender:cell.addButton,forLabel:itemAmount!)), for: .touchUpInside)
}
#objc func addItem(sender: UIButton, forLabel label:UILabel) {
print("Add Button Clicked")
}
You are using selector syntax incorrectly:
action: #selector(addItem(sender:cell.addButton,forLabel:itemAmount!))
Just say:
action: #selector(addItem)
Then, however, you will face a new problem. You think that somehow you can cause this button to call something called addItem(sender:forLabel:). You can't. Change the declaration of addItem to addItem(_ sender:UIButton). That is the only kind of function a button tap can call.
You will thus have the sender (the button), but you must figure out from there what the label is. (And this should be easy, because, knowing the button, you know the cell, and knowing the cell, you know the label.) You cannot pass the label as a parameter in response to the button tap — but you don't need to.
You need to create callback function in you cell
class AddItemCell: UITableViewCell {
var buttonClickCallback:(() -> Void)?
#IBAction func onButtonClick(_ sender:Any) {
buttonClickCallback?()
}
}
and assign buttonClickCallback in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell method
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as! AddItemCell
cell.setCell(item: item)
let itemAmount = cell.itemAmount as UILabel?
cell.buttonClickCallback = {
self.addItem(sender:cell.addButton,forLabel:itemAmount!)
}
}

How do I change font color for a specific cell from UITableViewRowAction?

I added a custom button using UITAbleViewRowAction so when the user swipes left on a row, he/she sees the button. How do I get the button to change the font color for that specific row when he/she presses that button? Thanks!
I'll assume you implemented tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?, then you can do this inside your action:
let action = UITableViewRowAction(style: .normal, title: "Action") { (action, indexPath) in
let cell = tableView.cellForRow(at: indexPath)
cell?.textLabel?.textColor = .red
tableView.setEditing(false, animated: true)
}
return [action]
If you've subclassed UITableViewCell, then you'll have to do
let cell = tableView.cellForRow(at: indexPath) as! MySubclassTableViewCell
and edit the appropiate label inside your class.
Alternatively, you could store the indexPath outside of the closure and reload the tableView.