data swift tidak ditransfer dari UIBarButtonItem ke viewcontroller lain

Sep 18 2020

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

askit Sep 22 2020 at 21:36

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.