Cannot trigger didSelectRowAt in UITableViewDelegate - ios

I'm trying to get the selected row in a table in Swift 4. The code presented for completeness, is as follows:
import UIKit
import WebKit
class FactorDetailsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var goalTitle: UILabel!
#IBOutlet weak var goalCopy: UITextView!
#IBOutlet weak var goalBenefit: UILabel!
#IBOutlet weak var goalName: UILabel!
#IBOutlet weak var graph: SimpleChart!
#IBOutlet weak var measurement: UILabel!
#IBOutlet weak var measurementRange: UILabel!
#IBOutlet weak var updated: UILabel!
#IBOutlet weak var factorCopy: UITextView!
#IBOutlet weak var impact: UILabel!
#IBOutlet weak var actionsTable: UITableView!
#IBOutlet weak var researchTable: UITableView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var stackView: UIStackView!
var factorData : Factor?
var currentCategory : FactorCategory?
var recommendedActions : [Action] = []
var relatedResearch : [Research] = []
var goal : Goal?
var reading:Double?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.title = factorData?.factorName
measurement.text = String(reading!)
self.actionsTable.delegate = self
self.actionsTable.dataSource = self
self.actionsTable.isEditing = false
self.researchTable.delegate = self
self.researchTable.dataSource = self
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Update", style: .done, target: self, action: #selector(addStuff))
goalCopy.text = goal?.copy
goalBenefit.text = "BIG BENEFIT"
goalTitle.text = goal?.title
for cat in (factorData?.categories)! {
let s = SimpleChartData(min : Double(cat.min), max : Double(cat.max), label : cat.label, label2 : String(cat.max))
if( graph.canLoad ) {
graph.data!.append(s)
}
}
graph.reading = reading!
// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
#objc func addStuff() {
// how does this work? Just takes you to the quiz again
let storyboard = UIStoryboard(name: "12Factor", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "AllQuestionViewController") as UIViewController
present(vc, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func configure( factor : Factor )
{
factorData = factor
let mirrored_object = Mirror(reflecting: HRResponses.shared)
reading = 1.0
for (_, attr) in mirrored_object.children.enumerated() {
if let property_name = attr.label as String? {
if factorData?.responseField == property_name {
if let a = attr.value as? String, let aDouble = Double(a) {
reading = aDouble
}
}
}
}
currentCategory = factor.categories.first( where: {$0.min < reading! && $0.max > reading! })
for aind in (currentCategory?.actions)! {
let act = SignalModel.model.actions.first( where: {$0.id == aind})
recommendedActions.append(act!)
}
for rind in (currentCategory?.research)! {
let act = SignalModel.model.research.first( where: {$0.id == rind})
relatedResearch.append(act!)
}
goal = SignalModel.model.goals.first( where: {$0.id == currentCategory?.goals[0]})
}
func tableView(_ tableView: UITableView,
willSelectRowAt indexPath: IndexPath) -> IndexPath? {
print("works?")
return nil
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if tableView == self.actionsTable {
let vc : ActionViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ActionViewController") as! ActionViewController
navigationController?.pushViewController(vc, animated: true)
}
if tableView == self.researchTable {
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of items in the sample data structure.
var count:Int?
if tableView == self.actionsTable {
count = currentCategory?.actions.count
}
if tableView == self.researchTable {
count = currentCategory?.research.count
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if tableView == self.actionsTable {
cell = tableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath as IndexPath)
let action = recommendedActions[indexPath.row]
(cell as! ActionCell).configure(a:action)
}
if tableView == self.researchTable {
cell = tableView.dequeueReusableCell(withIdentifier: "ResearchCell", for: indexPath as IndexPath)
let research = relatedResearch[indexPath.row]
(cell as! ResearchCell).configure(r:research)
}
return cell!
}
}
Now, that's too much code. The relevant parts are here:
self.actionsTable.delegate = self // yes, this is the delegate
self.actionsTable.dataSource = self
self.actionsTable.isEditing = false // no, we're not editing
As I understand it, this should be enough to have selections in the actionsTable trigger the
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
method. However, nothing happens. The other UITableViewDelegate methods are called, so this controller is the delegate for this table, however this one method is not ever triggered. Reading through the Apple documentation here I see that the method isn’t called when the table view is in editing mode (that is, the isEditing property of the table view is set to true), but my table isn't in editing mode. Is there something else that could be going wrong with my table that wouldn't allow it to send an event to a UITableViewDelegate? I suspect that this has something to do with the table being inside a UIScrollView, which I've read isn't best practice, but with the design I've been given, is non-negotiable sadly.

Your problem is not the delegate, all of that code is good. Your problem is that the parent scroll view is consuming the taps, not the table view. Remember, UITableView is a direct subclass of UIScrollView so placing a table view inside a scroll view is no different than placing a scroll view within a scroll view. UITableView has all of the default scroll view delegates built into it so just use those.
You should not embed UIWebView or UITableView objects in UIScrollView
objects. If you do so, unexpected behavior can result because touch
events for the two objects can be mixed up and wrongly handled.
Apple dox
I know it's not the answer you wanted because this wasn't your doing but I personally would not proceed with a hack. I would restructure the code and trim the controller down to one scroll view.

Related

How to pass selected row value as a public variable available to multiple view controllers?

How to have pass the value of a selected tableView to a public variable that can be accessed by multiple ViewControllers? Currently, in didSelectRowAt, I define the row selected as portfolio doing let portfolio = structure[indexPath.row] Now how can I save this value to perhaps some sort of variable that makes it avalible to multiple view controller?
I don't just mean pushing the value to whichever view controller is being presented when the cell is pressed, I need it be available to view controller past the .pushViewController.
In the past I tried using userdefaults, but this is not appropriate for values that are constantly changing and are not permanen.
import UIKit
class ScheduledCell: UITableViewCell {
#IBOutlet weak var ETALabel: UILabel!
#IBOutlet weak var cellStructure: UIView!
#IBOutlet weak var scheduledLabel: UILabel!
#IBOutlet weak var testingCell: UILabel!
#IBOutlet weak var pickupLabel: UILabel!
#IBOutlet weak var deliveryLabel: UILabel!
#IBOutlet weak var stopLabel: UILabel!
#IBOutlet weak var topBar: UIView!
}
class ToCustomerTableViewController: UITableViewController, UIGestureRecognizerDelegate {
var typeValue = String()
var driverName = UserDefaults.standard.string(forKey: "name")!
var structure = [AlreadyScheduledStructure]()
override func viewDidLoad() {
super.viewDidLoad()
fetchJSON()
//Disable delay in button tap
self.tableView.delaysContentTouches = false
tableView.tableFooterView = UIView()
}
private func fetchJSON() {
guard let url = URL(string: "https://example.com/example/example"),
let value = driverName.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "driverName=\(value)".data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
do {
self.structure = try JSONDecoder().decode([AlreadyScheduledStructure].self,from:data)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
catch {
print(error)
}
}.resume()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return structure.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "scheduledID", for: indexPath) as! ScheduledCell
let portfolio = structure[indexPath.row]
cell.stopLabel.text = "Stop \(portfolio.stop_sequence)"
cell.testingCell.text = portfolio.customer
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let portfolio = structure[indexPath.row]
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "scheduledDelivery")
print(portfolio.customer)
controller.navigationItem.title = navTitle
navigationController?.pushViewController(controller, animated: true)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200.0
}
}
You can use a function to pass an optional Value inside an extension, try the following:
From what I understood you want to pass values from your viewController and be able to get it from any other viewController..
extension UIViewController {
func passData(row: Int?) -> Int? {
var myValue = Int()
if row != nil {
myValue = row!
}
return myValue
}
}
in this function you can Pass the value you want and also retrieve it.
to pass data into the function simply use this :
passData(row: indexPath.row)
and if you want to retrieve the value of it from another viewController use this:
let myValue = passData(row: nil)
this way you could get the Data you pass from another viewController..
if that didn't work for you I'd suggest you use UserDefaults ..
I hope this could solve your problem.
You can use NSNotificationCenter and post value after selection and every subscribed controller will received a new value. For more info read this NSNotificationCenter addObserver in Swift

Can't call object from another class

I have a table view with expanding cells. The expanding cells come from a xib file. In the class of the table is where all of the code is that controls the expansion and pulling data from plist. I'm trying to add a close button but only want it to show when the cell is expanded. As it stands, I can't reference the button to hide it because it's in another class. Here is how I am trying to access it:
import UIKit
class SecondPolandViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var customTableViewCell:CustomTableViewCell? = nil
var items = [[String:String]]()
override func viewDidLoad() {
super.viewDidLoad()
**REFERENCING CLASS**
customTableViewCell = CustomTableViewCell()
let nib = UINib.init(nibName: "CustomTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "cell")
self.items = loadPlist()
}
func loadPlist()->[[String:String]]{
let path = Bundle.main.path(forResource: "PolandResourceList", ofType: "plist")
return NSArray.init(contentsOf: URL.init(fileURLWithPath: path!)) as! [[String:String]]
}
var selectedIndex:IndexPath?
var isExpanded = false
func didExpandCell(){
self.isExpanded = !isExpanded
self.tableView.reloadRows(at: [selectedIndex!], with: .automatic)
}
}
extension SecondPolandViewController:UITableViewDataSource, UITableViewDelegate{
***HIDING BUTTON***
let button = customTableViewCell?.closeButton
button?.isHidden = true
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.selectedIndex = indexPath
self.didExpandCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
cell.selectionStyle = .none
let item = self.items[indexPath.row]
cell.titleLabel.text = item["title"]
cell.shortLabel.text = item["short"]
cell.otherImage.image = UIImage.init(named: item["image"]!)
cell.thumbImage.image = UIImage.init(named: item["image"]!)
cell.longLabel.text = item["long"]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let height = UIScreen.main.bounds.height
if isExpanded && self.selectedIndex == indexPath{
//return self.view.frame.size.height * 0.6
return 400
}
return 110
//return height * 0.2
}
}
This does not hide it though.
Here is the xib that I am calling from if it helps. It is probably simple, I am just a newly self taught developer.
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var closeButton: UIImageView!
#IBOutlet weak var otherImage: UIImageView!
#IBOutlet weak var thumbImage: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var shortLabel: UILabel!
//#IBOutlet weak var longLabel: UITextView!
#IBOutlet weak var longLabel: UITextView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
//let width = UIScreen.main.bounds.width
//let height = UIScreen.main.bounds.height
//thumbImage.frame.size.width = height * 0.19
//thumbImage.frame.size.height = height * 0.19
}
}
It seems like that you just need to add these lines into cellForRowAt:indexPath method:
if indexPath == selectedIndexPath {
cell.closeButton.isHidden = false
} else {
cell.closeButton.isHidden = true
}
You may add them right before return line
The normal iOS answer for this is a delegate, but you could get away with a simple closure in this case.
In CustomTableViewCell, add
public var closeTapped: ((CustomTableViewCell) -> ())?
Then in that class, when close is tapped, call
self.closeTapped?(self)
In the VC, in cellForRowAt,
cell.closeTapped = { cell in
// do what you want with the VC
}
For delegates, this might help: https://medium.com/#jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef
The quick answer to why to prefer delegates over the closure is that its a handy way to group a bunch of these together. It's what UITableViewDelegate is (which you are using). Also, it's a common iOS idiom.
I wrote about this here: https://app-o-mat.com/post/how-to-pass-data-back-to-presenter for a similar situation (VC to VC communication)

Swift -> my prototype cell (UITableViewCell) doesn't show in my UIViewController with a UITableView

My storyboard looks like this
and my code is the following
UIViewController
class DownLoadSoundsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: View Controller Properties
let viewName = "DownLoadSoundsViewController"
#IBOutlet weak var visualEffectView: UIVisualEffectView!
#IBOutlet weak var dismissButton: UIButton!
#IBOutlet weak var downloadTableView: UITableView!
// MARK: Properties
var soundPacks = [SoundPack?]() // structure for downloadable sounds
override func viewDidLoad() {
super.viewDidLoad()
downloadTableView.dataSource = self
downloadTableView.delegate = self
downloadTableView.register(DownLoadTableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfSoundPacks
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let method = "tableView.cellForRowAt"
//if (indexPath as NSIndexPath).section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "downloadTableViewCell", for: indexPath) as! DownLoadTableViewCell
cell.backgroundColor = UIColor.green
if soundPacks[(indexPath as NSIndexPath).row]?.price == 0 {
cell.soundPackPriceUILabel.text = "FREE"
} else {
cell.soundPackPriceUILabel.text = String(format: "%.2", (soundPacks[(indexPath as NSIndexPath).row]?.price)!)
}
//cell.textLabel?.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackTitleUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackAuthorUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.author
cell.soundPackShortDescription.text = soundPacks[(indexPath as NSIndexPath).row]?.shortDescription
cell.soundPackImage.image = UIImage(named: "Placeholder Icon")
DDLogDebug("\(viewName).\(method): table section \((indexPath as NSIndexPath).section) row \((indexPath as NSIndexPath).row))")
return cell
//}
}
UItableViewCell
class DownLoadTableViewCell: UITableViewCell {
#IBOutlet weak var soundPackImage: UIImageView!
#IBOutlet weak var soundPackTitleUILabel: UILabel!
#IBOutlet weak var soundPackAuthorUILabel: UILabel!
#IBOutlet weak var soundPackShortDescription: UILabel!
#IBOutlet weak var soundPackPriceUILabel: UILabel!
let gradientLayer = CAGradientLayer()
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
}
}
But I get the following;
I am sure I am doing something small incorrectly, but as of yet can't figure it out. Looked through many examples included my own code where I have gotten this working before.
Not a single one of my settings for the tableview are getting invoked except the number of cells. But everything in;
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{...}
is not working.
Help is appreciated.
I think you need to reload the tableView after getting data from Firebase
self.saveMixesTableView.reloadData()

Calling a function on a UITableViewCell before the cell is returned?

I have this custom UITableViewCell:
class CircleOfTrustTableViewCell: UITableViewCell {
#IBOutlet var permissionTitle: UILabel!
#IBOutlet weak var permissionImage: UIImageView!
#IBOutlet weak var permissionSwitch: UISwitch!
#IBOutlet weak var spacingView: UIView!
// Update toggle based on user visibility and category type
func update(showUser: Bool, index: Int){
self.tag = index
let type = ProfileContentTypeActual.all[index]
self.permissionImage.image = UIImage(named: categoryImages[type]!)
self.permissionTitle.text = categoryNames[type]
if showUser {
self.permissionSwitch.tag = index
self.permissionSwitch.isEnabled = true
if let toggles = GlintUser.getThisUser().trust_toggle {
self.permissionSwitch.setOn(toggles.getState(type), animated: true)
}
} else {
self.permissionSwitch.setOn(false, animated: true)
self.permissionSwitch.isEnabled = false
}
}
}
I implement the cell this way:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
settingsTableView.register(UINib(nibName: "COTTableViewCell", bundle: nil), forCellReuseIdentifier: "cotCell")
let cotCell = (settingsTableView.dequeueReusableCell(withIdentifier: "cotCell") as! CircleOfTrustTableViewCell)
cotCell.update(showUser: showUser, index: indexPath.row)
return cotCell
}
My question is: Is it best practice to call the update function on the cell (to populate its data) or is it best to leave this in the cellForRowAtIndexPath method?

How to alter a button in cell on click in swift ios?

I have a table layout inside a view which as a custom cell,The problem I'm facing is that the cells inside has a button i want to hide the button in cell on clicking it(only the one that is clicked should be hidden) how can i do thing in correct method?
ScrollCell.swift
class ScrollCell: UITableViewCell {
#IBOutlet weak var ProfilePic: SpringImageView!
#IBOutlet weak var UserName: SpringButton!
#IBOutlet weak var Closet: UILabel!
#IBOutlet weak var Style: UILabel!
//------//
#IBOutlet weak var MianImg: UIImageView!
//-------//
#IBOutlet weak var ProductName: UILabel!
#IBOutlet weak var LoveCount: UIButton!
#IBOutlet weak var Discount: UILabel!
#IBOutlet weak var OrginalPrice: UILabel!
#IBOutlet weak var Unliked: UIButton!
#IBOutlet weak var Liked: UIButton!
#IBOutlet weak var Comment: UIButton!
#IBOutlet weak var Share: SpringButton!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func layoutSubviews() {
ProfilePic.layer.cornerRadius = ProfilePic.bounds.height / 2
ProfilePic.clipsToBounds = true
}
}
ScrollController.swift
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1 // however many sections you need
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(try! Realm().objects(Feed))
var FeedModel = Feed()
let realm = try! Realm()
let tan = try! Realm().objects(Feed).sorted("ID", ascending: false)
return tan.count // however many rows you need
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// get an instance of your cell
cell = tableView.dequeueReusableCellWithIdentifier("ScrollCellDqueue", forIndexPath: indexPath) as! ScrollCell
IndexPath = indexPath.row
var FeedModel = Feed()
let realm = try! Realm()
let tan = try! Realm().objects(Feed).sorted("ID", ascending: false)
cell.ProfilePic.kf_setImageWithURL(NSURL(string:tan[indexPath.row].ProfilePic)!)
cell.UserName.setTitle(tan[indexPath.row].FullName, forState: .Normal)
cell.Style.text = tan[indexPath.row].StyleType
if tan[indexPath.row].UserType == "store_front"{
cell.Closet.text = "Store Front"
}else if tan[indexPath.row].UserType == "normal"{
cell.Closet.text = "Pri Loved"
}
//-----//
var SingleImage:String = ""
var ImageArray = tan[indexPath.row].ImageArraySet.componentsSeparatedByString(",")
SingleImage = ImageArray[0]
cell.MianImg.kf_setImageWithURL(NSURL(string:SingleImage)!)
//-----//
cell.ProductName.text = tan[indexPath.row].ItemName
cell.OrginalPrice?.text = "\(tan[indexPath.row].OrginalPrice)"
cell.LoveCount.setTitle("\(tan[indexPath.row].LikeCount)"+" Loves", forState: .Normal)
cell.Discount.text = "\(tan[indexPath.row].Discount)"+" % off"
if(tan[indexPath.row].LikeStatus){
cell.Unliked.hidden = true
cell.Liked.hidden = false
}
else if (!tan[indexPath.row].LikeStatus){
cell.Unliked.hidden = false
cell.Liked.hidden = true
}
cell.Unliked.tag = tan[indexPath.row].ID
cell.Liked.tag = tan[indexPath.row].ID
return cell
}
#IBAction func LikeBtn(sender: AnyObject) {
print(sender.tag)
print(IndexPath)
//here i want to know who i can hide the button i have clicked ?
}
Here i want to access the cell in which button is clicked and make changes to UI item inside that cell how can i do that ?
There are many ways to do it. One possible solution is use block.
Add this to ScrollCell
var didLikedTapped: (() -> Void)?
and receive the event of the LikedButton in the cell
#IBAction func LikeBtn(sender: AnyObject) {
didLikedTapped?()
}
Then in cellForRowAtIndexPath of viewController add this
cell.didLikedTapped = {[weak self] in
print(IndexPath)
}
Liked is uibutton in ScrollCell, i don't known, why can you add IBAction for it in ScrollController? . You must implement it in ScrollCell And code:
#IBAction func LikeBtn(sender: UIButton) {
print(sender.tag)
sender.hiden = true
}
And i think, if you have only one UIbutton, it will better. In there, like and unlike is 2 state of uibutton(seleted and none). When you click the button, change it's state
Update:
class sampleCell: UITableViewCell{
#IBOutlet var btnLike : UIButton!
#IBOutlet var btnUnLike : UIButton! // frame of 2 button is equal
override func awakeFromNib() {
super.awakeFromNib()
self.btnUnLike.hidden = true
// ...
}
func updateData(data:AnyObject){ // data's type is Feed
// set data for cell
// i think you should implement in here. and in ScollController call : cell.updateData() , it's better
/* e.x
self.ProductName.text = tan[indexPath.row].ItemName
self.OrginalPrice?.text = "\(tan[indexPath.row].OrginalPrice)"
self.LoveCount.setTitle("\(tan[indexPath.row].LikeCount)"+" Loves", forState: .Normal)
self.Discount.text = "\(tan[indexPath.row].Discount)"+" % off"
*/
}
#IBAction func likeTap(sender:UIButton){ // rememeber set outlet event for btnLike and btnUnLike is this function
if sender == self.btnLike{
self.btnLike.hidden = true
self.btnUnLike.hidden = false
// do s.t
}else if sender == self.btnUnLike{
self.btnLike.hidden = false
self.btnUnLike.hidden = true
// do s.t
}
}
}
Check if the following code help
#IBAction func LikeBtn(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
}
give the LikeBtn the property indexpath, in cellForRowAtIndexPath method, pass the indexPath to the LikeBtn, then you will know which cell's LikeBtn clicked.
class LikeBtn: UIButton {
var indexPath: NSIndexPath?
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
// here pass the indexpath to your button
cell.likeBtn.indexPath = indexPath
return cell
}
#IBAction func likeTap(sender: LikeBtn){
if let indexPath = sender.indexPath {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
//here you will know the exact cell, now you can hide or show your buttons
}
}
}

Resources