I have an issue with my delegate for UIStepper, TableViewCell and TableViewController. I am unable to pass a delegate command to my TableViewCell in the TableViewController.
My TableViewCell code is as below:
CampTableCell.swift
import UIKit
protocol ReviewCellDelegate{
func stepperButton(stepper_value:Int)
}
class CampTableCell: UITableViewCell {
#IBOutlet var campqty: UILabel!
#IBOutlet var stepper: UIStepper!
var delegate:ReviewCellDelegate!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func stepperValueChanged(sender: UIStepper) {
self.delegate.stepperButton(Int(stepper.value))
campqty.text = String(Int(stepper.value))
}
}
The start of my TableGenController.swift is this:
class TableGenController: UITableViewController, UISearchBarDelegate, ReviewCellDelegate {
and I have added this function (as a test):
func stepperButton(stepper_value:Int) {
print("Value Changed!")
}
Next, I believe, is I have to add this under viewDidLoad:
CampTableCell.delegate = self
However, this causes an error stating that:
Instance member 'delegate' cannot be used on type 'CampTableCell'
I might be doing something conceptually wrong, but it's been difficult to find resources for this particular setup. Would be really grateful for some help on this, thanks!
I'm not proficient in delegates, but have you tried removing the line with the error? I'm not sure you need it.
Also I think you can remove self in
self.delegate.stepperButton(Int(stepper.value))
Related
I've a custom UITableViewCell, in that I've two UILabels & one UIButton. I'm able to load data...and display it as per requirement.
Problem Statement-1: Now problem exist in my UIButton, which is in my UICustomTableViewCell. Due to this I'm unable to handle click event on that UIButton.
Problem Statement-2: On button Click I have to identify the index of that Button click and pass data to next ViewController using segue.
Now have a look on...what did I've tried for this...
Yes, first-of-all I have thought that Binding IBOutlet action in my CustomCell will resolve my problem...but actually it doesn't solved my problem.
After that I've accessed button using .tag and initialised index path.row to it.
But it won't helped me.
So now I'm using Protocol oriented concept using delegate to handle click event on my UIButton which is available in CustomCell.
What did I tried:
SwiftyTableViewCellDelegate:
protocol SwiftyTableViewCellDelegate : class {
func btnAuditTrailDidTapButton(_ sender: LeadCustomTableViewCell)
}
CustomTableViewCell with delegate:
class LeadCustomTableViewCell: UITableViewCell {
#IBOutlet weak var lblMeetingPersonName: UILabel!
#IBOutlet weak var lblPolicyNo: UILabel!
#IBOutlet weak var btnLeadAuditTrail: UIButton!
weak var delegate: SwiftyTableViewCellDelegate?
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
#IBAction func btnAuditTrailTapped(_ sender: UIButton) {
delegate?.btnAuditTrailDidTapButton(self)
}
}
ViewController implementing delegate:
class LeadViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwiftyTableViewCellDelegate {
//IBOutlet Connections - for UITableView
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//setting dataSource & delegates of UITableView with this ViewController
self.tableView.dataSource = self
self.tableView.delegate = self
//Reloading tableview with updated data
self.tableView.reloadData()
//Removing extra empty cells from UITableView
self.tableView.tableFooterView = UIView()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:LeadCustomTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! LeadCustomTableViewCell
//Assigning respective array to its associated label
cell.lblMeetingPersonName.text = (meetingPersonNameArray[indexPath.section] )
cell.lblPolicyNo.text = (String(policyNoArray[indexPath.section]))
cell.btnLeadAuditTrail.tag = indexPath.section
cell.delegate = self
return cell
}
//This is delegate function to handle buttonClick event
func btnAuditTrailDidTapButton(_ sender: LeadCustomTableViewCell) {
guard let tappedIndexPath = tableView.indexPath(for: sender) else { return }
print("AuditTrailButtonClick", sender, tappedIndexPath)
}
Don't know why this is not working.
Link the touch up inside event in cellForRow by adding the following code:
cell.btnLeadAuditTrail.addTarget(self, action:#selector(btnAuditTrailDidTapButton(_:)), for: .touchUpInside)
I have used the same nib file to populated a UITableView. There are 2 different functionalities I have built out for these cells. If you anywhere on the cell other than a small button it runs a function and segues to another page. However if you click the small button, I want to update the UITableView and input a cell below the clicked cell, as a sort of dropdown. I have the below to successfully run a separate functionality:
import UIKit
class ContactCell: UITableViewCell {
//below are the outlets for the conact cells
#IBOutlet weak var msgStatus: UIView!
#IBOutlet weak var contactName: UILabel!
#IBOutlet weak var dropDown: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
msgStatus.layer.cornerRadius = msgStatus.frame.size.width/2
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func dropDown(_ sender: Any) {
print("selected drop down")
}
}
Moving forward I need to be able to get the index of the current cell and perform a UITableView update from the UITableViewCell's class. How would I be able to do this?
You could do this with delegation. Create a delegate protocol for your ContactCell:
protocol ContactCellDelegate {
func pleaseAddDropdown(to: ContactCell)
}
Then set up a delegate parameter for the cell:
var delegate: ContactCellDelegate?
Then subscribe your table view to the ContactCellDelegate protocol (you will have to subclass if you are using a standard UITableView). This means you will need to write an implementation of pleaseAddDropdown() for your table view class. When you dequeue a cell make sure the delegate parameter is assigned to your table view.
Now in your implementation of dropdown() you just need to do something like:
guard let _ = delegate else { return }
delegate!.pleaseAddDropdown(to: self)
Which will send that message up to the table view which can take the appropriate action.
Hope that helps.
I'm trying to pass text from one textField to another textField (both of them are located in two different containerViews). I try to accomplish this with delegate. I've already read tons of related questions here, at stack overflow and read a couple of articles, so, I think I'm doing well except one thing: I don't know how to delegate without segue. Here's the code:
protocol AddOneWordViewControllerDelegate: class {
func changeTexeValue(_ text: String?)
}
class AddOneWordViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var oneWordAddWord: UITextField!
weak var delegate: AddOneWordViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func addOneWordWordChanged(_ sender: UITextField) {
self.delegate?.changeTexeValue(oneWordAddWord.text!)
print ("Value of the textField did change \(oneWordAddWord.text!)")
} // this action is from textField, named "Value Changed"
}
class AddTwoWordsViewController: UIViewController, UITextFieldDelegate, AddOneWordViewControllerDelegate {
#IBOutlet weak var twoWordsAddWord: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
func changeTexeValue(_ text: String?) {
self.twoWordsAddWord.text = text
print("Delegate is working")
}
}
I am trying to create a UITableView with 3 different custom UITableViewCell. They all share some common elements such as a UILabel that is called questionLabel.
I have three types of cells
OneTextFieldTableViewCell
TwoLabelTableViewCell
ThreeLabelTableViewCell
I want these cells to inherit from a FormTableViewCell that share common UI elements like the questionLabel as mentioned above.
Code:
class OneTextFieldTableViewCell: FormItemTableViewCell {
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var answerTextField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
FormItemTableViewCell
class FormItemTableViewCell: UITableViewCell {
#IBOutlet weak var questionLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I am getting errors:
Cannot override with a stored property 'questionLabel'
Getter for 'questionLabel' with Objective-C selector 'questionLabel' conflicts with getter for 'questionLabel' from superclass 'FormItemTableViewCell' with the same Objective-C selector
Setter for 'questionLabel' with Objective-C selector 'setQuestionLabel:' conflicts with setter for 'questionLabel' from superclass 'FormItemTableViewCell' with the same Objective-C selector
Your variable questionLabel is already defined in your superclass. No need to mention it again. That's the whole point of inheritance. Your subclasses inherit the variables of its super classes.
IBOutlet, IBAction, IBDesignable are just labels. Doesn't matter where you add them in the inheritance tree. Once there, you have informed the compiler/Xcode that this is a "special" function or variable.
So if your class has a function #IBAction func doStuff() , you can override it as override func doStuff() and still connect to it from within IB. Same for overriding IBOutlet in case you want to add willSet or didSet or replace the getter/setter functions.
I have a UITableViewCell subclass where I have connected a UISwitch from a custom prototype cell. (data are passed in the Table View from a previous ViewController)
When I Change view controllers the state of the UISwitchchanges back to default
I need some way to remember the state of the switch while navigating through the app.
I have searched a few other topics, but nothing seemed to fall in my case.
Here is the code:
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet weak var myStaticSwitch: UISwitch!
#IBOutlet weak var cellLabel: UILabel!
#IBAction func mySwitch(sender: UISwitch) {
if myStaticSwitch.on {
self.cellLabel.text = "on"
//Do other things
}
else {
self.cellLabel.text = "off"
//Do other things
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
You should have a model object that is used to determine the state of the UI representing it. This object can be saved to disk, persisted with Core Data, or even synced to a remote web service.
When you next encounter a need to display any UI related to the object, you can always check its properties to determine what to show. Your UI action method then simply updates the model representation:
#IBAction func mySwitch(sender: UISwitch) {
myModelObject.enabled = myStaticSwitch.on
}
The UI (e.g., your table cell) then looks for changes to enabled and updates the cellLabel as needed.
here is the code. Now I need a way to refer to each Switch separately and not as a whole.
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet weak var myStaticSwitch: UISwitch!
#IBAction func mySwitch(sender: UISwitch) {
myStaticSwitch.on = (sender as UISwitch).on //Bool
NSUserDefaults.standardUserDefaults().setBool(myStaticSwitch.on, forKey: "autoAdjustSettings")
NSUserDefaults.standardUserDefaults().synchronize()
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
myStaticSwitch.on = NSUserDefaults.standardUserDefaults().boolForKey("autoAdjustSettings")
// Configure the view for the selected state
}
}