#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 всему продукту. И когда вы обновляете количество своего продукта, обновите значение модели для того же самого и перезагрузите свою таблицу.