Я пытаюсь создать приложение, которое может сохранять товар в корзину (заказ) с использованием представления коллекции, внутри каждой ячейки представления сбора имеется шаговый шаг.
вот файл проекта на диске Google: https://drive.google.com/file/d/1Ax7VLpI8Vb2jFSJxn_Ss_TjEECbDt-fs/view?usp=sharing
и вот скриншот приложения (пожалуйста, игнорируйте ужасный интерфейс):
В ячейке просмотра коллекции отображается 6 товаров. каждая ячейка представления коллекции имеет метку имени, кнопку добавления в корзину и степпер.
кнопка «Добавить в корзину», и шаговый двигатель имеет тот же размер и расположен в том же месте, после нажатия кнопки «Добавить в корзину» он будет скрывать кнопку «Добавить в корзину» и будет отображать степпер в виде картинки Вот:
http://g.recordit.co/DAKMvFwQs4.gif
Я использую приведенный ниже код для своей ячейки представления коллекции, я передаю данные с использованием протокола и шаблона делегата:
protocol OrderCellDelegate {
func addToCartButtonDidTapped(at selectedIndexPath: IndexPath)
func stepperDidTapped(at selectedIndexPath:IndexPath, counterValue: Int)
}
class OrderCell: UICollectionViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var stepper: GMStepper!
@IBOutlet var addToCartButton: UIButton!
var productData : Product? {
didSet {
setStepper()
updateUI()
}
}
var indexPath: IndexPath?
var delegate: OrderCellDelegate?
@IBAction func AddToCartButtonDidTapped(_ sender: Any) {
guard let selectedIndexPath = indexPath else {return}
self.delegate?.addToCartButtonDidTapped(at: selectedIndexPath)
}
@IBAction func stepperButtonDidTapped(_ sender: Any) {
guard let selectedIndexPath = indexPath else {return}
let value = Int(stepper.value)
self.delegate?.stepperDidTapped(at: selectedIndexPath, counterValue: value)
}
func setStepper() {
guard let product = productData else {return}
stepper.value = Double(product.quantityInCart)
stepper.autorepeat = false
stepper.minimumValue = 0
stepper.maximumValue = 100
stepper.stepValue = 1.0
}
func updateUI() {
guard let product = productData else {return}
nameLabel.text = product.name
setCartAndStepperButton()
}
private func setCartAndStepperButton() {
guard let selectedProduct = productData else {return}
func showStepperButton(status: Bool) {
// to decide whether to show stepper or add to cart button.
stepper.isHidden = !status
stepper.isEnabled = status
addToCartButton.isHidden = status
addToCartButton.isEnabled = !status
}
if selectedProduct.quantityInCart == 0 {
showStepperButton(status: false)
} else {
showStepperButton(status: true)
stepper.value = Double(selectedProduct.quantityInCart)
}
}
}
и вот код для моего контроллера вида:
class ViewController: UIViewController, OrderCellDelegate {
@IBOutlet weak var collectionView: UICollectionView!
var order : Order!
var allProducts = [Product]()
override func viewDidLoad() {
super.viewDidLoad()
order = Order.getOrderFromRealmDatabase()
allProducts = Product.fetchProductData()
}
func addToCartButtonDidTapped(at selectedIndexPath: IndexPath) {
print("A")
let selectedProduct = allProducts[selectedIndexPath.item]
Order.addProductToOrderRealmDatabase(userOrder: order, selectedProduct: selectedProduct)
collectionView.reloadData()
}
func stepperDidTapped(at selectedIndexPath: IndexPath, counterValue: Int) {
print("B")
}
}
// DATA SOURCE
extension ViewController : UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allProducts.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "orderCell", for: indexPath) as! OrderCell
cell.productData = allProducts[indexPath.item]
cell.delegate = self
cell.indexPath = indexPath
return cell
}
}
и проблема .....
, когда я нажимаю кнопку добавления в корзину, на моем контроллере просмотра срабатывает addToCartButtonDidTapped
. но ... я не понимаю, почему, когда я нажимаю кнопку добавления в корзину, он также вызывает метод stepperDidTapped
, поэтому, когда addToCartButtonDidTapped
, будет автоматически запускаться stepperDidTapped
метод. print («A») и print («B») запускаются одновременно.
Как вы можете видеть, метод stepperDidTapped
должен срабатывать только тогда, когда я нажимаю на степпер, а не на кнопку добавления в корзину, я использую метод 2 дифференцирования на OrderCellDelegate
Я не понимаю, почему. У меня есть неправильный способ реализовать степпер внутри ячейки вида коллекции? честно говоря, я не уверен, что в моем коде реализован шаговый шаг внутри представления коллекции выше.
вот файл проекта: https://drive.google.com/file/d/1Ax7VLpI8Vb2jFSJxn_Ss_TjEECbDt-fs/view?usp=sharing
вот модель товара:
import RealmSwift
class Product : Object {
@objc dynamic var productID : Int = 0
@objc dynamic var name : String = ""
@objc dynamic var unitPrice: Double = 0.0
@objc dynamic var quantityInCart : Int = 0
@objc dynamic var descriptionProduct : String = ""
@objc dynamic var hasBeenAddedToCart : Bool = false
override static func primaryKey() -> String? {
return "productID"
}
convenience init(productID: Int, name: String, unitPrice: Double, descriptionProduct: String) {
self.init()
self.productID = productID
self.name = name
self.unitPrice = unitPrice
self.descriptionProduct = descriptionProduct
}
static func fetchProductData() -> [Product] {
let product1 = Product(productID: 1, name: "Product1", unitPrice: 1000, descriptionProduct: "Description of Product 1")
let product2 = Product(productID: 2, name: "Product2", unitPrice: 2000, descriptionProduct: "Description of Product 2")
let product3 = Product(productID: 3, name: "Product3", unitPrice: 3000, descriptionProduct: "Description of Product 3")
let product4 = Product(productID: 4, name: "Product4", unitPrice: 4000, descriptionProduct: "Description of Product 4")
let product5 = Product(productID: 5, name: "Product5", unitPrice: 5000, descriptionProduct: "Description of Product 5")
let product6 = Product(productID: 6, name: "Product6", unitPrice: 6000, descriptionProduct: "Description of Product 6")
return [product1,product2,product3,product4,product5,product6]
}
static func changeProductQuantityInRealmDatabase(selectedProduct: Product, quantity: Int) {
guard let selectedProductInRealmDatabase = RealmService.shared.realm.objects(Product.self).filter("productID == %@", selectedProduct.productID).first else {return}
RealmService.shared.updateOnCertainKey(object: selectedProductInRealmDatabase, for: ["quantityInCart": quantity])
}
}
и вот модель заказа:
import RealmSwift
class Order : Object {
@objc dynamic var userID: String = ""
var products = List<Product>()
convenience init (userID: String, products: List<Product>) {
self.init()
self.userID = "1"
self.products = products
}
//MARK: - Realm Related
static func getOrderFromRealmDatabase() -> Order {
let userID = "1"
let realmService = RealmService.shared.realm
let allOrder = realmService.objects(Order.self)
let theOrder = allOrder.filter("userID CONTAINS[cd] %@", userID).first
if let userOrder = theOrder {
return userOrder
} else {
// Order never setted up before in Realm database container
// then create Order in realm database
let newOrder = Order()
newOrder.userID = userID
newOrder.products = List<Product>()
RealmService.shared.save(object: newOrder)
return newOrder
}
}
static func addProductToOrderRealmDatabase(userOrder: Order, selectedProduct: Product) {
// to check wheter the selected product from user is already in Order or not
if userOrder.products.filter("productID == %@", selectedProduct.productID).first == nil {
// check if the selected product has already available in Product.self database or not
if let matchingProduct = RealmService.shared.realm.objects(Product.self).filter("productID == %@", selectedProduct.productID).first {
RealmService.shared.save(expression: {
userOrder.products.append(matchingProduct)
matchingProduct.hasBeenAddedToCart = true
matchingProduct.quantityInCart = 1
})
} else {
RealmService.shared.save(expression: {
userOrder.products.append(selectedProduct)
selectedProduct.hasBeenAddedToCart = true
selectedProduct.quantityInCart = 1
})
}
}
}
}