Обнаружение нажатия на кнопку в UITableViewCell для UITableView, содержащего несколько разделов в Swift

#ios #swift #uitableview

#iOS #swift #uitableview

Вопрос:

В UITableViewCell я пытаюсь нажать на кнопку «AddToCart», и, немедленно нажав на это, я скрываю кнопку «AddToCart» и показываю кнопки » » и «-«; Это работает отлично, но, к сожалению, я вижу, что аналогичные действия произошли и в других ячейках из-за того, что кнопка «AddToCart» скрыта в ячейках 8-го, 15-го, 22-го ряда.

Не могли бы вы помочь мне решить эту проблему.

 import Foundation
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
import SDWebImage

class ProductListScreen: UITableViewController {
    
    
    var dbRef: DatabaseReference!
    var tempProducts: [Product] = []
    var imagesurlslist = [String]()
    
    
    
    let activityIndicatorView = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.gray)
    var products: [Product] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        activityIndicatorView.transform = CGAffineTransform(scaleX: 3, y: 3);
        tableView.backgroundView = activityIndicatorView
        activityIndicatorView.startAnimating()
         dbRef = Database.database().reference().child("xxxxx").child("0").child("xxxxxxx")
        dbRef.observe(DataEventType.value) { (snapshotAA) in
            for snapshotchild in snapshotAA.children.allObjects as! [DataSnapshot] {
                let snapshotchildobj = snapshotchild.value as? [String: AnyObject]
                let image:String  = snapshotchildobj?["imageurl"] as? String ?? ""
                let title:String  = snapshotchildobj?["name"] as? String ?? ""
                let price:String  = snapshotchildobj?["price"] as? String ?? ""
                let units:String  = snapshotchildobj?["units"] as? String ?? ""
                let quantity:String  = snapshotchildobj?["quantity"] as? String ?? ""
                let quantityunits:String  = quantity   " "   units as? String ?? ""
                self.tempProducts.append(Product(url: image,title: title,price: price, quantity: quantityunits))
                self.imagesurlslist.append(image)
            }
            self.products = self.tempProducts
            self.tableView.reloadData()
        }
    }
    
    
    
    var showImageIndex : Int?
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(products.count)
        return products.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    

        let product = products[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell",for: indexPath) as! ProductCell
        showImageIndex = indexPath.row
        cell.setProduct(product: product)
        let image = imagesurlslist[indexPath.row]
        cell.productImage!.sd_setImage(with: URL(string: image), placeholderImage: UIImage(named: "xxxxxxxx"))
        
        cell.cartButtonOutlet.tag = indexPath.row
        
        cell.tapCartButton = {
            print(indexPath.row)
            print(ProductCell().addtocartbuttonclicked)
            ProductCell().addtocartbuttonclicked = "Yes"
            
        }
        return cell;
    }
}





*******************************


import Foundation
import UIKit

class ProductCell: UITableViewCell {
    var index: IndexPath?
    var isAddToCartVisible: Bool?
    
    var addtocartbuttonclicked:String = "No"
    
    @IBOutlet weak var productImage: UIImageView!
    @IBOutlet weak var productTitle: UILabel!
    @IBOutlet weak var productPrice: UILabel!
    @IBOutlet weak var productQuantity: UILabel!
    
    var tapCartButton: (() -> Void)? = nil

    let productImageView: UIImageView = {
        let productImage = UIImageView()
        productImage.image = UIImage(named: "xxxxxxxxx")
        productImage.translatesAutoresizingMaskIntoConstraints = false
        productImage.layer.cornerRadius = 20
        productImage.layer.masksToBounds = true
        return productImage
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
        addSubview(productImageView)
//        ios 9 constraints
        productImageView.leftAnchor.constraint(equalTo:self.leftAnchor, constant: 10).isActive = true
        productImageView.centerYAnchor.constraint(equalTo:self.centerYAnchor).isActive = true
        productImageView.widthAnchor.constraint(equalToConstant: 40)
        productImageView.heightAnchor.constraint(equalToConstant: 40)
        
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    

    
    func setProduct(product: Product){
        productTitle.text = product.title
        productPrice.text = product.price
        productQuantity.text = product.quantity
    }

    
//    **************** Objects Initialization ****************
    

    
    
    @IBOutlet weak var postiveButtonLabel: UIButton!
    
    @IBOutlet weak var negativeButtonLabel: UIButton!
    
    
     @IBAction func positiveButton(_ sender: UIButton) {
    print("pblisterener clicked")
    let mystring = String(describing: (selectedQuantity.text)!).trimmingCharacters(in: .whitespacesAndNewlines)
    let myInt1 = Int(mystring)
    print (myInt1! 1)
    selectedQuantity.text = " " String(myInt1! 1)

}

@IBAction func negativeButton(_ sender: Any) {
    print("mbnlistener clicked")
    let mystring = String(describing: (selectedQuantity.text)!).trimmingCharacters(in: .whitespacesAndNewlines)
    let myInt1 = Int(mystring)
    if(myInt1 != 1){
        selectedQuantity.text = " " String(myInt1!-1)
    }
}
    
    @IBOutlet weak var selectedQuantity: UILabel!
    @IBOutlet weak var cartButtonOutlet: UIButton!
    @IBAction func cartClick(_ sender: Any) {
        addtocartbuttonclicked = "Yes"
        print(addtocartbuttonclicked)
        if( addtocartbuttonclicked == "Yes" ) {
        tapCartButton?()
        cartButtonOutlet.isHidden = true
        postiveButtonLabel.isHidden = false
        negativeButtonLabel.isHidden = false
        selectedQuantity.isHidden = false
        
        }
        addtocartbuttonclicked = "Yes"
    }
    
    
    

    

}



Please refer this Video for more Info : https://youtu.be/kUMLAmksr-w  

введите описание изображения здесь

Комментарии:

1. Эй, эта проблема возникает из-за «dequeueReusableCell». Вы можете решить эту проблему с помощью дополнительной переменной (var isAddToCartVisible: Bool?), т. е. определенной в вашей модели продукта, сначала установите для нее значение false, а при нажатии на любой путь индекса установите значение true для этого продукта. если вы снова столкнулись с той же проблемой, обновите здесь модель вашего продукта. Я исправлю это.

2. Ашутош, я новичок в Swift, не могли бы вы помочь мне с приведенным выше кодом для моих нужд… Заранее большое спасибо..

3. Эй, реализована ли какая-либо модель для получения этих данных при сетевом вызове. Если да, пожалуйста, поделитесь кодом вашей модели, чтобы я обновил эти данные модели и предоставил решение. Кроме того, обновите код функции «cell.setProduct(product: продукт)» в вашем вопросе.

4. Ашутош, я обновил свой вопрос полным кодом, я застрял здесь на 3 дня, не могли бы вы помочь мне решить это.. Заранее спасибо..

5. var products: [Product] = [] в этой строке вы использовали структуру / класс «Product», не могли бы вы, пожалуйста, добавить этот код сюда. Я могу понять проблему, потому что мне приходится сталкиваться с тем же

Ответ №1:

При прокрутке через UITableView или a UICollectionView эти представления будут повторно использовать ячейки, которые исчезают с экрана с помощью dequeueReusableCell вызова функции. Это означает, что вы должны переопределить или восстановить состояния этих ячеек, поскольку они не будут изменены представлениями таблицы или коллекции. Это лучше всего сделать, переопределив func prepareForReuse() из UITableViewCell , где вы должны удалить состояния этой ячейки. В вашем случае вам следует скрыть кнопку «Добавить в корзину» и, что также важно, отменить tapCartButton закрытие (т. Е. установить для него значение nil, поскольку это может вызвать много проблем в будущем).

Эта функция будет вызываться всякий раз, когда эта конкретная функция UITableViewCell будет повторно использоваться UITableView .

Ответ №2:

Вашей структуре данных необходимо свойство, с помощью которого вы отслеживаете, была ли она «Добавлена в корзину» или нет

Когда вы задаете данные своей ячейки, покажите или скройте кнопку:

 func setProduct(product: Product){
    productTitle.text = product.title
    productPrice.text = product.price
    productQuantity.text = product.quantity
    
    // show or hide the add to cart button
    if product.isInCart {
        cartButtonOutlet.isHidden = true
    } else {
        cartButtonOutlet.isHidden = false
    }
}
  

Затем в закрытии, которое вы создаете в cellForRowAt :

     cell.tapCartButton = {
        print(indexPath.row)
        
        // this is wrong...
        // you create a NEW ProductCell and print the value of addtocartbuttonclicked
        //print(ProductCell().addtocartbuttonclicked)
        // then you create ANOTHER NEW ProductCell and set the value of addtocartbuttonclicked
        //ProductCell().addtocartbuttonclicked = "Yes"
        // closure ends, and your NEW ProductCell goes away
        
        // instead, you want to update your data
        // something like
        self.products[indexPath.row].isInCart = true
        
    }
  

Ответ №3:

Согласно вашему коду, я предполагаю, что ваш «Продукт» представляет собой что-то вроде:-

 struct Product {
    var url: String?
    var title: String?
    var price: String?
    var quantity: String?
    var isAddedInCart: Bool? // I have added extra varible to resolve your issue
}
  

Теперь я должен изменить ваш существующий код с помощью переменной «isAddedInCart», пытаясь устранить вашу проблему.

Используйте это следующим образом:-

 import Foundation
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
import SDWebImage

class ProductListScreen: UITableViewController {


    var dbRef: DatabaseReference!
    var tempProducts: [Product] = []
    var imagesurlslist = [String]()



    let activityIndicatorView = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.gray)
    var products: [Product] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        activityIndicatorView.transform = CGAffineTransform(scaleX: 3, y: 3);
        tableView.backgroundView = activityIndicatorView
        activityIndicatorView.startAnimating()
         dbRef = Database.database().reference().child("xxxxx").child("0").child("xxxxxxx")
        dbRef.observe(DataEventType.value) { (snapshotAA) in
            for snapshotchild in snapshotAA.children.allObjects as! [DataSnapshot] {
                let snapshotchildobj = snapshotchild.value as? [String: AnyObject]
                let image:String  = snapshotchildobj?["imageurl"] as? String ?? ""
                let title:String  = snapshotchildobj?["name"] as? String ?? ""
                let price:String  = snapshotchildobj?["price"] as? String ?? ""
                let units:String  = snapshotchildobj?["units"] as? String ?? ""
                let quantity:String  = snapshotchildobj?["quantity"] as? String ?? ""
                let quantityunits:String  = quantity   " "   units as? String ?? ""
                self.tempProducts.append(Product(url: image,title: title,price: price, quantity: quantityunits, isAddedInCart: false))
                self.imagesurlslist.append(image)
            }
            self.products = self.tempProducts
            self.tableView.reloadData()
        }
    }



    var showImageIndex : Int?
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(products.count)
        return products.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let product = products[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell",for: indexPath) as! ProductCell
        showImageIndex = indexPath.row
        cell.setProduct(product: product)
        let image = imagesurlslist[indexPath.row]
        cell.productImage!.sd_setImage(with: URL(string: image), placeholderImage: UIImage(named: "xxxxxxxx"))

        cell.cartButtonOutlet.tag = indexPath.row

        cell.tapCartButton = {
            print(indexPath.row)
            print(ProductCell().addtocartbuttonclicked)
            ProductCell().addtocartbuttonclicked = "Yes"
            product.isAddedInCart = true
            self.tableView.reloadData()

        }
        return cell;
    }
}





//*******************************


import Foundation
import UIKit

class ProductCell: UITableViewCell {
    var index: IndexPath?
    var isAddToCartVisible: Bool?

    var addtocartbuttonclicked:String = "No"

    @IBOutlet weak var productImage: UIImageView!
    @IBOutlet weak var productTitle: UILabel!
    @IBOutlet weak var productPrice: UILabel!
    @IBOutlet weak var productQuantity: UILabel!

    var tapCartButton: (() -> Void)? = nil

    let productImageView: UIImageView = {
        let productImage = UIImageView()
        productImage.image = UIImage(named: "nammadukhaninkannada")
        productImage.translatesAutoresizingMaskIntoConstraints = false
        productImage.layer.cornerRadius = 20
        productImage.layer.masksToBounds = true
        return productImage
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
        addSubview(productImageView)
//        ios 9 constraints
        productImageView.leftAnchor.constraint(equalTo:self.leftAnchor, constant: 10).isActive = true
        productImageView.centerYAnchor.constraint(equalTo:self.centerYAnchor).isActive = true
        productImageView.widthAnchor.constraint(equalToConstant: 40)
        productImageView.heightAnchor.constraint(equalToConstant: 40)

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }



    func setProduct(product: Product){
        productTitle.text = product.title
        productPrice.text = product.price
        productQuantity.text = product.quantity
        if product.isAddedInCart == true {
           cartButtonOutlet.isHidden = true
           postiveButtonLabel.isHidden = false
           negativeButtonLabel.isHidden = false
           selectedQuantity.isHidden = false
        }
        else{
            cartButtonOutlet.isHidden = false
            postiveButtonLabel.isHidden = true
            negativeButtonLabel.isHidden = true
            selectedQuantity.isHidden = true
        }
    }


//    **************** Objects Initialization ****************




    @IBOutlet weak var postiveButtonLabel: UIButton!

    @IBOutlet weak var negativeButtonLabel: UIButton!


    @IBAction func positiveButton(_ sender: Any) {
    }


    @IBAction func negativeButton(_ sender: Any) {
    }

    @IBOutlet weak var selectedQuantity: UILabel!
    @IBOutlet weak var cartButtonOutlet: UIButton!
    @IBAction func cartClick(_ sender: Any) {
        addtocartbuttonclicked = "Yes"
        print(addtocartbuttonclicked)
        if( addtocartbuttonclicked == "Yes" ) {
        tapCartButton?()
        }
        addtocartbuttonclicked = "Yes"
    }

}
  

Комментарии:

1. Большое спасибо Ashutosh, это работает отлично.. Я вижу аналогичные проблемы для кнопок » » и «-«, тем не менее, я буду реализовывать ту же логику и для них.. Еще раз большое спасибо.

2. Ахутош, мне нужна от вас еще одна помощь, теперь я вижу аналогичную проблему с положительной и отрицательной кнопками, я могу видеть, что уменьшение приращения происходит с двумя кнопками, но это отражается на кнопках других ячеек. По умолчанию я показываю количество как «1», когда я нажимаю «AddToCart» оттуда, оно ведет себя в соответствии с положительной кнопкой и отрицательной кнопкой Примечание: Я обновил свой код для положительной и отрицательной кнопок в самом коде, не могли бы вы помочь мне с этим.. Заранее большое спасибо..

3. Аналогично переменной «AddedInCart», создайте одну переменную из «numberOfProduct» и присвоите 1 всему продукту. И когда вы обновляете количество своего продукта, обновите значение модели для того же самого и перезагрузите свою таблицу.