swift data not transferred from UIBarButtonItem to another viewcontroller

核能气质少年 提交于 2021-02-17 06:52:27

问题


This is an extension of an earlier question:- ios Swift Items do not get added to cart

The original issue is resolved. Now I have a supplementary hitch:-

The issue is in CartViewController - When I click on "Checkout(2)" rightBarButtonItem in the ProductViewController, it shows error in CartviewController's "numberOfRowsInSection" function - Kindly see image & codes below:-

class 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))"
   }
 }

The issue is in CartViewController - When I click on "Checkout(2)" rightBarButtonItem in the ProductViewController(see image above), it shows error in CartviewController's "numberOfRowsInSection" function - see CartViewController code below:-

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

My Models -

struct Product -

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

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

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

--

The UITableViewCells -

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

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

The segues are connected properly. So, I suspect rightBarButtonItem i.e. Checkout(2) to another CartViewcontroller.

I have been thinking over it for quite some time.

I would sincerely appreciate your assistance. It would mean a lot to me.


回答1:


It was a rookie mistake. I had named the segue incorrectly. It is “showCart” in the ProductViewController, while I was naming it “ShowCart” i.e. upper case letter “S”. It is puny but formidable ! Anyways, thanks for looking into my problem.



来源:https://stackoverflow.com/questions/63956420/swift-data-not-transferred-from-uibarbuttonitem-to-another-viewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!