Member 12959299 Ответов: 1

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.

Я думал об этом довольно долго.

Я был бы искренне признателен вам за помощь. Это будет много значить для меня.

1 Ответов

Рейтинг:
9

Member 12959299

Это была ошибка новичка. Я неправильно назвал сегмент. Это “showCart” в ProductViewController, а я называл его “ShowCart”, т. е. заглавные буквы “S”. Он ничтожен, но грозен ! В любом случае, спасибо, что изучили мою проблему.