Swift данные не передаются из uibarbuttonitem в другой viewcontroller
Проблема заключается в CartViewController - когда я нажимаю на "Checkout(2)" rightBarButtonItem в ProductViewController, он показывает ошибку в функции CartviewController "numberOfRowsInSection" - пожалуйста, смотрите изображение и коды ниже:-
Я размышлял над этим довольно долго. Пожалуйста, спасите мою шкуру.
Подробная ссылка на проблему находится здесь :- uitableview - swift данные не передаются из UIBarButtonItem в другой viewcontroller - переполнение стека[^]
Что я уже пробовал:
1 class ProductViewController - 2 3 import UIKit 4 5 class ProductViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 6 let sections = ["Section A", "Section B"] 7 let rowspersection = [3,1] 8 fileprivate var cart = Cart() 9 10 @IBOutlet weak var tableView: UITableView! 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 tableView.delegate = self 14 tableView.dataSource = self 15 } 16 17 override func viewWillAppear(_ animated: Bool) { 18 super.viewWillAppear(animated) 19 20 //Workaround to avoid the fadout the right bar button item 21 self.navigationItem.rightBarButtonItem?.isEnabled = false 22 self.navigationItem.rightBarButtonItem?.isEnabled = true 23 24 //Update cart if some items quantity is equal to 0 and reload the product table and right button bar item 25 26 cart.updateCart() 27 self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))" 28 tableView.reloadData() 29 } 30 31 override func didReceiveMemoryWarning() { 32 super.didReceiveMemoryWarning() 33 // Dispose of any resources that can be recreated. 34 } 35 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 36 if segue.identifier == "showCart" { 37 if let cartViewController = segue.destination as? CartViewController { 38 cartViewController.cart = self.cart 39 } 40 } 41 } 42 43 func numberOfSections(in tableView: UITableView) -> Int { 44 return sections.count 45 } 46 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 47 return rowspersection[section] 48 } 49 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 50 let cell = tableView.dequeueReusableCell(withIdentifier: "ProductTableViewCell") as! ProductTableViewCell 51 cell.delegate = self // original issue was here, now resolved. 52 53 var index = indexPath.row 54 if indexPath.section != 0, rowspersection.count > indexPath.section - 1{ 55 index += rowspersection[indexPath.section - 1] 56 } 57 58 if index < productarray.count{ 59 let data = productarray[index] 60 cell.name?.text = data.name 61 cell.imageView?.image = data.imagename 62 } 63 let product = productarray[indexPath.item] 64 cell.setButton(state: self.cart.contains(product: product)) 65 return cell 66 } 67 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 68 return 44 69 } 70 71 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 72 switch(section) { 73 case 0:return "Section A" 74 case 1:return "Section B" 75 default :return "" 76 77 } 78 } 79 } 80 81 extension ProductViewController: CartDelegate { 82 83 // MARK: - CartDelegate 84 func updateCart(cell: ProductTableViewCell) { 85 guard let indexPath = tableView.indexPath(for: cell) else { return } 86 let product = productarray[indexPath.item] 87 88 //Update Cart with product 89 cart.updateCart(with: product) 90 self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))" 91 } 92 }Проблема в том, что
CartViewController
- Когда я нажимаю на кнопку "Оформить заказ(2)" rightBarButtonItem
в ProductViewController
(см. изображение выше), он показывает ошибку в CartviewController
'с "numberOfRowsInSection
"функция - см. CartViewController
код ниже:-1 import UIKit 2 3 class CartViewController: UIViewController { 4 @IBOutlet weak var tableView: UITableView! 5 @IBOutlet weak var totalView: UIView! 6 @IBOutlet weak var totalLabel: UILabel! 7 8 var cart: Cart? = nil 9 fileprivate let reuseIdentifier = "CartItemCell" 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 tableView.tableFooterView = UIView(frame: .zero) 13 } 14 } 15 16 extension CartViewController: UITableViewDelegate, UITableViewDataSource { 17 // MARK: - Table view data source 18 func numberOfSections(in tableView: UITableView) -> Int { 19 // #warning Incomplete implementation, return the number of sections 20 return 1 21 } 22 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 23 // #warning Incomplete implementation, return the number of rows 24 return (cart?.items.count)! /*Error - Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)*/ 25 } 26 27 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 28 let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! CartItemTableViewCell 29 30 if let cartItem = cart?.items[indexPath.item] { 31 cell.delegate = self as CartItemDelegate 32 33 // cell.nameLabel.text = cartItem.product.name 34 // cell.priceLabel.text = cartItem.product.price 35 cell.quantityLabel.text = String(describing: cartItem.quantity) 36 37 cell.quantity = cartItem.quantity 38 // cell.contentView.backgroundColor = !cell.decrementButton.isEnabled ? .white : .blue 39 } 40 return cell 41 } 42 } 43 44 45 extension CartViewController: CartItemDelegate { 46 47 // MARK: - CartItemDelegate 48 func updateCartItem(cell: CartItemTableViewCell, quantity: Int) { 49 guard let indexPath = tableView.indexPath(for: cell) else { return } 50 guard let cartItem = cart?.items[indexPath.row] else { return } 51 52 //Update cart item quantity 53 cartItem.quantity = quantity 54 55 //Update displayed cart total 56 // guard let total = cart?.total else { return } 57 //totalLabel.text = String(total) 58 // print(total) 59 } 60 }
моя модель -
1 struct Product - 2 3 import UIKit 4 5 struct Product:Equatable { 6 let name : String 7 var quantity : Int 8 var price : Double 9 let imagename: UIImage 10 // var subTotal : Double { 11 //return Double(quantity) * price } 12 } 13 var productarray = [Product(name: "a", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "CakeImage")), 14 Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "PeasImge")),Product(name: "a", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "vectorlogo")), 15 Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "blue")),] 16 17 class CartItem - 18 19 import Foundation 20 21 class CartItem { 22 var quantity : Int = 1 23 var product : Product 24 // var subTotal : Float { get { return Float(product.price) * Float(quantity) } } 25 init(product: Product) { 26 self.product = product 27 } 28 } 29 30 class Cart - 31 32 import Foundation 33 34 class Cart { 35 var items : [CartItem] = [] 36 } 37 38 extension Cart { 39 40 /* var total: Float { 41 get { return items.reduce(0.0) { value, item in 42 value + item.subTotal 43 } 44 } 45 }*/ 46 47 var totalQuantity : Int { 48 get { return items.reduce(0) { value, item in 49 value + item.quantity 50 } 51 } 52 } 53 func updateCart(with product: Product) { 54 if !self.contains(product: product) { 55 self.add(product: product) 56 } else { 57 self.remove(product: product) 58 } 59 } 60 func updateCart() { 61 62 for item in self.items { 63 if item.quantity == 0 { 64 updateCart(with: item.product) 65 } 66 } 67 } 68 69 func add(product: Product) { 70 let item = items.filter { $0.product == product } 71 72 if item.first != nil { 73 item.first!.quantity += 1 74 } else { 75 items.append(CartItem(product: product)) 76 } 77 } 78 79 func remove(product: Product) { 80 guard let index = items.firstIndex(where: { $0.product == product }) else { return} 81 items.remove(at: index) 82 } 83 84 85 func contains(product: Product) -> Bool { 86 let item = items.filter { $0.product == product } 87 return item.first != nil 88 } 89 }UITableViewCells -
1 class ProductTableViewCell - 2 3 import UIKit 4 protocol CartDelegate { 5 func updateCart(cell: ProductTableViewCell) } 6 class ProductTableViewCell: UITableViewCell { 7 weak var myParent:ProductViewController? 8 @IBOutlet weak var name: UILabel! 9 @IBOutlet weak var price: UILabel! 10 @IBOutlet weak var imagename: UIImageView! 11 @IBOutlet weak var addToCartButton: UIButton! 12 13 var delegate: CartDelegate? 14 15 override func awakeFromNib() { 16 super.awakeFromNib() 17 // Initialization code 18 19 addToCartButton.layer.cornerRadius = 5 20 addToCartButton.clipsToBounds = true 21 } 22 23 func setButton(state: Bool) { 24 addToCartButton.isSelected = state 25 addToCartButton.backgroundColor = (!addToCartButton.isSelected) ? .black : .red 26 } 27 28 @IBAction func addToCart(_ sender: Any) { 29 setButton(state: !addToCartButton.isSelected) 30 self.delegate?.updateCart(cell: self) 31 } 32 } 33 34 class CartItemTableViewCell- 35 36 import UIKit 37 38 protocol CartItemDelegate { 39 func updateCartItem(cell: CartItemTableViewCell, quantity: Int) 40 } 41 class CartItemTableViewCell: UITableViewCell { 42 43 @IBOutlet weak var nameLabel: UILabel! 44 @IBOutlet weak var priceLabel: UILabel! 45 46 @IBOutlet weak var incrementButton: UIButton! 47 @IBOutlet weak var decrementButton: UIButton! 48 @IBOutlet weak var quantityLabel: UILabel! 49 50 var delegate: CartItemDelegate? 51 var quantity: Int = 1 52 53 override func awakeFromNib() { 54 super.awakeFromNib() 55 // Initialization code 56 57 incrementButton.layer.cornerRadius = 10 58 incrementButton.clipsToBounds = true 59 60 decrementButton.layer.cornerRadius = 10 61 decrementButton.clipsToBounds = true 62 } 63 64 override func setSelected(_ selected: Bool, animated: Bool) { 65 super.setSelected(selected, animated: animated) 66 } 67 68 @IBAction func updateCartItemQuantity(_ sender: Any) { 69 if (sender as! UIButton).tag == 0 { 70 quantity = quantity + 1 71 } else if quantity > 0 { 72 quantity = quantity - 1 73 } 74 75 decrementButton.isEnabled = quantity > 0 76 decrementButton.backgroundColor = !decrementButton.isEnabled ? .gray : .black 77 78 self.quantityLabel.text = String(describing: quantity) 79 self.delegate?.updateCartItem(cell: self, quantity: quantity) 80 } 81 }Сегменты соединены правильно. Так что, я подозреваю
rightBarButtonItem
т. е. проверка(2) на другой CartViewcontroller
.Я думал об этом довольно долго.
Я был бы искренне признателен вам за помощь. Это будет много значить для меня.