why my stepper value inside collection view cell d

2019-09-02 07:48发布

问题:

I have collection view cell, and I have stepper and product name label inside the collection view cell. I have six products displayed on the collection view cell. I want to add the product to cart / order by tapping the Add To Cart Button.

once the add to cart button is tapped, then the add to cart button will be hided and it will show the stepper, like the image below.

here is my code for my collection view cell:

protocol OrderCellDelegate {
   func stepperValueChange(at selectedIndexPath: IndexPath, stepperValue: Int)
}


class OrderCell: UICollectionViewCell {

    @IBOutlet weak var stepper: GMStepper!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet var addToCartButton: UIButton!

    var productData : Product? {
        didSet {
            updateUI()
        }
    }

    var indexPath: IndexPath?
    var delegate: OrderCellDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()

        setStepper()

    }


    @IBAction func addToCartButtonDidTapped(_ sender: Any) {
        stepper.value = 1.0
    }


    @IBAction func stepperValueChanged(_ sender: Any) {

        print("stepper value: \(stepper.value)")

        guard let selectedIndexPath = indexPath else {return}
        let value = Int(stepper.value)
        self.delegate?.stepperValueChange(at: selectedIndexPath, stepperValue: value)
    }




    func setStepper() {
        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)
        }


    }


}

as you can see in the addToCartButtonDidTapped method above, I set the stepper value to be 1 programmatically, I expect the number in the blue stepper above to be 1, but it shows zero instead of one (like the screenshot above)

I connect the stepperValueChanged method using @IBAction using 'value change' as the sent event. so when the stepper.value = 1.0 is triggered inside addToCartButtonDidTapped , then all the code inside stepperValueChanged method will automatically triggered

but why it become zero even though I force it to be one ? could you please help me with this one ?

here is the file project in google drive: https://drive.google.com/file/d/1VBR0HkR2Wb2RF2m1CC3zI8a5hJipHW7W/view

here is my view controller code:

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 stepperValueChange(at selectedIndexPath: IndexPath, stepperValue: Int) {

        guard let userOrder = order else {return}
        let selectedProduct = allProducts[selectedIndexPath.item]

        let maximumQuantityOfProduct = 100
        let minimumQuantityOfProduct = 1

        if stepperValue == minimumQuantityOfProduct - 1 {
            // remove the product from the cart if the stepper value is one below the minimum allowable quantity

            Order.removeProductFromOrderRealmDatabase(userOrder: userOrder, selectedProduct: selectedProduct)
            Product.changeProductQuantityInRealmDatabase(selectedProduct: selectedProduct, quantity: 0)

        } else if stepperValue == minimumQuantityOfProduct {

            // it means add to cart button is tapped

            if userOrder.products.filter("productID == %@", selectedProduct.productID).first == nil {
                Order.addProductToOrderRealmDatabase(userOrder: userOrder, selectedProduct: selectedProduct)
            }  else {
                Order.removeProductFromOrderRealmDatabase(userOrder: userOrder, selectedProduct: selectedProduct)
            }


        } else if stepperValue > minimumQuantityOfProduct && stepperValue <= maximumQuantityOfProduct {

            Product.changeProductQuantityInRealmDatabase(selectedProduct: selectedProduct, quantity: stepperValue)

        }

        collectionView.reloadData()

    }





}


// 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
    }

}

and here is the product code:

    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])

    }



}

here is the order model:

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) {


        // 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
            })

        }


    }



    static func removeProductFromOrderRealmDatabase(userOrder: Order, selectedProduct: Product) {


        // to check wheter the selected product from user is already in Order or not

        if let matchingProduct = userOrder.products.filter("productID == %@", selectedProduct.productID).first {

            RealmService.shared.save(expression: {
                matchingProduct.hasBeenAddedToCart = false
                guard let index = userOrder.products.index(where: {$0.productID == matchingProduct.productID}) else {return}
                userOrder.products.remove(at: index)
                matchingProduct.quantityInCart -= 1
            })



        }


    }






}