快速如何将表格视图划分为多个部分并添加到购物车正常工作?

2023-12-31

这让我陷入了疯狂。我已经思考这个问题很长一段时间了,尝试了所有的技巧,但没有运气。

如果您能解决我的问题,我将不胜感激。

我的问题是,当我将 Product ViewController 分为几个部分时:-

i) 单元格(即图像)的顺序不正确。

ii) 添加到购物车按钮无法正常工作。

注意: - 如果以下代码对您来说似乎很广泛,请保留其余代码,只需查看 ProductViewController - 我只想能够按照我的意愿将 ProductViewController 划分为多个部分,并且“添加到购物车”按钮正常工作,很可能无需更改模型。我放置了冗长的代码以防万一,也为了展示我已经尝试过的内容(在其他人的帮助下)。

如果你时间很紧,我也在这里问了这个问题的不全面或较小的版本 -带部分的 UITableView 在所有部分中重复单元格数据 https://stackoverflow.com/q/63918495/7444874,但我仍然要求您阅读下面的完整代码 -

稍后我将阐明这两点。首先请看我的代码 -

Models -

结构产品 -

import UIKit
 struct Product:Equatable {
let name : String
var quantity : Int
var price : Double
let imagename: UIImage
  // var subTotal : Double {
    //return Double(quantity) * price }
}
 var productarray = [Product(name: "a", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "blue")),
               Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "CakeImage")),Product(name: "c", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "vectorlogo")),
                Product(name: "d", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "PeasImge")),Product(name: "e", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "castle")),
                Product(name: "f", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "scoobydoo")),Product(name: "g", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "ufo")),
                Product(name: "h", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "wolfsky")),Product(name: "i", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "universe")),
                Product(name: "j", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "werewolf")),Product(name: "k", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "galaxy"))]

购物车项目类 -

 import Foundation
  
   class CartItem {
  var quantity : Int = 1
 var product : Product
 //  var subTotal : Float { get { return Float(product.price) * Float(quantity) } }
 init(product: Product) {
    self.product = product
   }
 }

类购物车 -

 import Foundation

class Cart {
var items : [CartItem] = []
}

extension Cart {


/* var total: Float {
    get { return items.reduce(0.0) { value, item in
        value + item.subTotal
        }
    }
}*/

var totalQuantity : Int {
    get { return items.reduce(0) { value, item in
        value + item.quantity
        }
    }
}
func updateCart(with product: Product) {
    if !self.contains(product: product) {
        self.add(product: product)
    } else {
        self.remove(product: product)
    }
}
func updateCart() {
    
    for item in self.items {
        if item.quantity == 0 {
            updateCart(with: item.product)
        }
    }
}

func add(product: Product) {
    let item = items.filter { $0.product == product }
    
    if item.first != nil {
        item.first!.quantity += 1
    } else {
        items.append(CartItem(product: product))
    }
}

func remove(product: Product) {
    guard let index = items.firstIndex(where: { $0.product == product }) else { return}
    items.remove(at: index)
}


func contains(product: Product) -> Bool {
    let item = items.filter { $0.product == product }
    return item.first != nil
  }
}

产品视图控制器类 -

import UIKit
class ProductViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let sections = ["Section A", "Section B","Section C", "Section D","Section E"]
let rowspersection = [2,3,2,2,2]
fileprivate var cart = Cart()

@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self    }

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    //Workaround to avoid the fadout the right bar button item
    self.navigationItem.rightBarButtonItem?.isEnabled = false
    self.navigationItem.rightBarButtonItem?.isEnabled = true
    
    //Update cart if some items quantity is equal to 0 and reload the product table and right button bar item
    
    cart.updateCart()
   self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))"
    tableView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
 if segue.identifier == "showCart" {
 if let cartViewController = segue.destination as? CartViewController {
 cartViewController.cart = self.cart
    }
 }
 }

func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return rowspersection[section]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell   {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ProductTableViewCell") as!   ProductTableViewCell
    cell.delegate = self 
    
    var index = indexPath.row
    if indexPath.section != 0, rowspersection.count > indexPath.section - 1{
        index += rowspersection[indexPath.section - 1]
    }
    
    if index < productarray.count {
        let data = productarray[index]
        cell.name?.text = data.name
        cell.imageView?.image =  data.imagename
        
        let product = productarray[index]
        cell.setButton(state: self.cart.contains(product: product))
      }
    return cell
  }
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 44
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    switch(section) {
    case 0:return "Section A"
    case 1:return "Section B"
    case 2:return "Section C"
    case 3:return "Section D"
    case 4:return "Section E"
   default :return ""
        
    }
  }
}
 extension ProductViewController: CartDelegate {

// MARK: - CartDelegate
func updateCart(cell: ProductTableViewCell) {
    guard let indexPath = tableView.indexPath(for: cell) else { return }
    var index = indexPath.row
    if indexPath.section != 0, rowspersection.count > indexPath.section - 1{
        index += rowspersection[indexPath.section - 1]
    }
    
    if index < productarray.count{
        let product = productarray[index]
        
        //Update Cart with product
        cart.updateCart(with: product)
        self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))"
    }
    }
  }

产品 TableViewCell 类 -

  import UIKit

  protocol CartDelegate {
func updateCart(cell: ProductTableViewCell) }

class ProductTableViewCell: UITableViewCell {
weak var myParent:ProductViewController?
  @IBOutlet weak var name: UILabel!
 @IBOutlet weak var price: UILabel!
 @IBOutlet weak var imagename: UIImageView!
 @IBOutlet weak var addToCartButton: UIButton!

var delegate: CartDelegate?

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    
   addToCartButton.layer.cornerRadius = 5
  addToCartButton.clipsToBounds = true
 }

 func setButton(state: Bool) {
    addToCartButton.isSelected = state
    addToCartButton.backgroundColor = (!addToCartButton.isSelected) ? .black : .red
 }

 @IBAction func addToCart(_ sender: Any) {
    setButton(state: !addToCartButton.isSelected)
    self.delegate?.updateCart(cell: self)
   }
}

类 CartViewController -

  import UIKit

class CartViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var totalView: UIView!
@IBOutlet weak var totalLabel: UILabel!

var cart: Cart? = nil
fileprivate let reuseIdentifier = "CartItemCell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: .zero)
 }
}

 extension CartViewController: UITableViewDelegate, UITableViewDataSource {
 // MARK: - Table view data source
 func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
 }
 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int  {
 // #warning Incomplete implementation, return the number of rows
   return (cart?.items.count)!
   }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->    UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! CartItemTableViewCell

   if let cartItem = cart?.items[indexPath.item] {
    cell.delegate = self as CartItemDelegate
    
       //  cell.nameLabel.text = cartItem.productarray.name
       // cell.priceLabel.text = cartItem.product.displayPrice()
       // cell.quantityLabel.text = String(describing: cartItem.quantity)
      
     cell.quantity = cartItem.quantity
     }
 return cell
     }
   }

extension CartViewController: CartItemDelegate {

  // MARK: - CartItemDelegate
   func updateCartItem(cell: CartItemTableViewCell, quantity: Int) {
  guard let indexPath = tableView.indexPath(for: cell) else { return      }
  guard let cartItem = cart?.items[indexPath.row] else { return }

    //Update cart item quantity
   cartItem.quantity = quantity
    }
  }

类 CartItem TableViewCell -

import UIKit

protocol CartItemDelegate {
func updateCartItem(cell: CartItemTableViewCell, quantity: Int) }
                                                                 
  class CartItemTableViewCell: UITableViewCell {

@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var priceLabel: UILabel!

@IBOutlet weak var incrementButton: UIButton!
@IBOutlet weak var decrementButton: UIButton!
@IBOutlet weak var quantityLabel: UILabel!

var delegate: CartItemDelegate?
var quantity: Int = 1

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    
    incrementButton.layer.cornerRadius = 10
    incrementButton.clipsToBounds = true
    
    decrementButton.layer.cornerRadius = 10
    decrementButton.clipsToBounds = true
   }

   override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
  }

   @IBAction func updateCartItemQuantity(_ sender: Any) {
    if (sender as! UIButton).tag == 0 {
        quantity = quantity + 1
    } else if quantity > 0 {
        quantity = quantity - 1
    }
    
    decrementButton.isEnabled = quantity > 0
    decrementButton.backgroundColor = !decrementButton.isEnabled ? .gray : .black
    
    self.quantityLabel.text = String(describing: quantity)
    self.delegate?.updateCartItem(cell: self, quantity: quantity)
    }
 }

结果是这样的。请先看图片,然后我会解释什么是错误的

1)模型“结构产品”中的图像/单元按顺序排列 - 蓝色、CakeImage、vectorlogo、PeasImage、城堡、scoobydoo、ufo、wolfsky、宇宙、狼人、星系

但模拟器中的图像(见上图)的模式不稳定 -

A 部分:蓝色,蛋糕图像,矢量标志

B 部分:矢量标志、PeasImge、城堡。

C 部分:豌豆图像,城堡。

D 部分:豌豆图像,城堡。

E 部分:豌豆图像,城堡。

  1. 只是图像并不不稳定,单元格上的“添加”按钮也不稳定 - 单击下部部分中的“添加”按钮 有时增加和减少 rightBarButtonItem 即 Chekcout(4)

我之前曾问过一个类似版本的问题,用户 PGDev 建议 -

不是创建不同的数组,而是创建自定义类型的单个数组并将其用作 tableView 的数据源。例子:

struct Section {
let name: String
let products: [Product] 
 }

let sections = [
Section(name: "Section A", products: [Product(name: "a", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "blue")),
               Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "CakeImage"))]),
 Section(name: "Section B", products: [Product(name: "c", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "vectorlogo")),
                Product(name: "d", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "PeasImge")),Product(name: "e", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "castle"))]),
 Section(name: "Section C", products: [Product(name: "f", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "scoobydoo")),Product(name: "g", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "ufo"))]),
 Section(name: "Section D", products: [Product(name: "h", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "wolfsky")),Product(name: "i", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "universe"))]),
 Section(name: "Section E”, products: [ Product(name: "j", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "werewolf")),Product(name: "k", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "galaxy"))]]) 
 ]

即使用sections数组作为数据源以避免很多混乱。

我也准备这样做,也许这种方法更好,但随后我将不得不更改代码的许多部分。该怎么做呢?

我只想实现以下目标——

  1. 按照我的意愿将 ProdutViewcontroller 的单元格/图像分成几个部分。

  2. 将数据添加到 rightBarButtonItem,即正确结帐,随后应将其传输到 CartViewController。

.. 别着急。花你自己的时间来解决问题,但对我来说修复它们至关重要,因为我需要为生产应用程序提供类似的代码。我陷入了两难的境地。请保释我。我将非常感激。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速如何将表格视图划分为多个部分并添加到购物车正常工作? 的相关文章

随机推荐