data swift tidak ditransfer dari UIBarButtonItem ke viewcontroller lain
Ini merupakan perpanjangan dari pertanyaan sebelumnya: - Item Swift ios tidak ditambahkan ke keranjang
Masalah asli teratasi. Sekarang saya memiliki halangan tambahan: -
Masalahnya ada di CartViewController - Ketika saya mengklik "Checkout (2)" rightBarButtonItem di ProductViewController, ini menunjukkan kesalahan dalam fungsi "numberOfRowsInSection" CartviewController - Mohon lihat gambar & kode di bawah ini: -
kelas ProductViewController -
import UIKit
class ProductViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let sections = ["Section A", "Section B"]
let rowspersection = [3,1]
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 // original issue was here, now resolved.
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[indexPath.item]
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"
default :return ""
}
}
}
extension ProductViewController: CartDelegate {
// MARK: - CartDelegate
func updateCart(cell: ProductTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
let product = productarray[indexPath.item]
//Update Cart with product
cart.updateCart(with: product)
self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))"
}
}
Masalahnya ada di CartViewController - Ketika saya mengklik "Checkout (2)" rightBarButtonItem di ProductViewController (lihat gambar di atas), ini menunjukkan kesalahan dalam fungsi "numberOfRowsInSection" CartviewController - lihat kode CartViewController di bawah ini: -
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)! /*Error - Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)*/
}
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.product.name
// cell.priceLabel.text = cartItem.product.price
cell.quantityLabel.text = String(describing: cartItem.quantity)
cell.quantity = cartItem.quantity
// cell.contentView.backgroundColor = !cell.decrementButton.isEnabled ? .white : .blue
}
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
//Update displayed cart total
// guard let total = cart?.total else { return }
//totalLabel.text = String(total)
// print(total)
}
}
Model Saya -
Produk struct -
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: "CakeImage")),
Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "PeasImge")),Product(name: "a", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "vectorlogo")),
Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "blue")),]
kelas 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
}
}
kelas Cart -
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
}
}
-
UITableViewCells -
kelas 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)
}
}
kelas 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)
}
}
Segue terhubung dengan benar. Jadi, saya menduga rightBarButtonItem yaitu Checkout (2) ke CartViewcontroller lain.
Saya telah memikirkannya cukup lama.
Saya sangat menghargai bantuan Anda. Itu akan sangat berarti bagiku.
Jawaban
Itu adalah kesalahan pemula. Saya telah salah menamai segue. Ini adalah "showCart" di ProductViewController, sementara saya menamainya "ShowCart" yaitu huruf besar "S". Itu lemah tapi tangguh! Bagaimanapun, terima kasih telah melihat masalah saya.