如何解决快速地将Tableview划分为多个部分,并正确地添加到购物车中?
这使我陷入疯狂。我已经思考了很长时间,尝试了交易的所有技巧,但是没有运气。
如果您解决我的问题,我将感激不尽。
我的问题是,当我将ProductViewController分为几部分时:-
i)单元格即图像的顺序不正确。
ii)添加到购物车按钮无法正常工作。
注意:-如果下面的代码对您来说很广泛,请保留其余代码,只需查看ProductViewController-我只希望能够按照我的意愿将ProductViewController划分为多个部分,请添加到购物车按钮正常工作,很可能无需更改模型。我输入了冗长的代码以防万一,并展示了我的尝试(在他人的帮助下)。
如果您时间很短,我也在这里询问了问题的不完整版本或较小版本-UITableView with Sections Repeating cell data in all the sections,但是我仍然会要求您在下面阅读我的完整代码-
稍后,我将阐明这两点。首先请看我的代码-
模型-
结构产品-
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",imagename:#imageLiteral(resourceName: "vectorlogo")),Product(name: "d",imagename:#imageLiteral(resourceName: "PeasImge")),Product(name: "e",imagename:#imageLiteral(resourceName: "castle")),Product(name: "f",imagename:#imageLiteral(resourceName: "scoobydoo")),Product(name: "g",imagename:#imageLiteral(resourceName: "ufo")),Product(name: "h",imagename:#imageLiteral(resourceName: "wolfsky")),Product(name: "i",imagename:#imageLiteral(resourceName: "universe")),Product(name: "j",imagename:#imageLiteral(resourceName: "werewolf")),Product(name: "k",imagename:#imageLiteral(resourceName: "galaxy"))]
CartItem类-
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
}
}
ProductViewController类-
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]
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))"
}
}
}
ProductTableViewCell类-
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
}
}
CartItemTableViewCell类-
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,PeasImge,城堡,scoobydoo,ufo,wolfsky,宇宙,狼人,银河
但模拟器中的图像(请参见上图)处于不稳定模式-
A部分:蓝色,CakeImage,vectorlogo
B部分:vectorlogo,PeasImge,城堡。
C节:豌豆城堡,城堡。
D节:豌豆城堡,城堡。
E节:豌豆城堡,城堡。
之前我曾问过类似版本的问题,用户PGDev曾提出过建议-
不是创建不同的数组,而是创建一个自定义类型的单个数组,并将其用作tableView的dataSource。示例:
struct Section {
let name: String
let products: [Product]
}
let sections = [
Section(name: "Section A",products: [Product(name: "a",imagename:#imageLiteral(resourceName: "CakeImage"))]),Section(name: "Section B",products: [Product(name: "c",imagename:#imageLiteral(resourceName: "castle"))]),Section(name: "Section C",products: [Product(name: "f",imagename:#imageLiteral(resourceName: "ufo"))]),Section(name: "Section D",products: [Product(name: "h",imagename:#imageLiteral(resourceName: "universe"))]),Section(name: "Section E”,products: [ Product(name: "j",imagename:#imageLiteral(resourceName: "galaxy"))]])
]
即使用sections数组作为数据源,以避免造成很多混乱。
我也准备这样做,也许这种方法更好,但随后我将不得不更改代码的许多部分。该怎么做?
我只想实现以下目标-
-
根据需要将ProdutViewcontroller的单元格/图像划分为多个部分。
-
向rightBarButtonItem添加数据,即正确结帐,随后应将其转移到CartViewController。
..不要着急。请花一些时间来整理问题,但是对我来说,解决这些问题至关重要,因为我需要生产应用程序使用类似的代码。我身陷困境。请保释我。我非常有义务。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。