快速数据未从UIBarButtonItem传输到另一个ViewController [英] swift data not transferred from UIBarButtonItem to another viewcontroller
问题描述
这是先前问题的扩展:-
问题出在CartViewController中-当我单击 Checkout(2)时, ProductViewController中的rightBarButtonItem(请参见上图),它显示CartviewController的 numberOfRowsInSection错误函数-请参见下面的CartViewController代码:-
导入UIKit
类CartViewController:UIViewController {
@IBOutlet弱var tableView:UITableView!
@IBOutlet弱var totalView:UIView!
@IBOutlet弱var totalLabel:UILabel!
var购物车:购物车? = nil
fileprivate let复用标识符= CartItemCell;
覆写func viewDidLoad(){
super.viewDidLoad()
tableView.tableFooterView = UIView(frame:.zero)
}
}
扩展名CartViewController:UITableViewDelegate,UITableViewDataSource {
//标记:-表格视图数据源
func numberOfSections(在tableView中:UITableView)-> Int {
// // warning不完整的实现,返回段数
return 1
}
func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {
// #warning实现不完整,返回
返回的行数(购物车?.items.count)! / *错误-线程1:EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)* /
}
func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:复用标识符,for:indexPath)为!如果让cartItem = cart?.items [indexPath.item] {
cell.delegate = self as CartItemDelegate
// cell.nameLabel.text =,则CartItemTableViewCell
cartItem.product.name
// cell.priceLabel.text = cartItem.product.price
cell.quantityLabel.text = String(描述:cartItem.quantity)
单元格。数量= cartItem.quantity
// cell.contentView.backgroundColor =!cell.decrementButton.isEnabled? .white:.blue
}
返回单元格
}
}
扩展名CartViewController:CartItemDelegate {
//标记:-CartItemDelegate
func updateCartItem(cell:CartItemTableViewCell,Quantity:Int){
保护let indexPath = tableView.indexPath(for:cell)else {return}
保护let cartItem = cart?.items [indexPath.row] else {return}
//更新购物车项目数量
cartItem.quantity =数量
//更新显示的购物车总计
//警卫让总数= cart?.total else {return}
//totalLabel.text =字符串(总计)
//打印(总计)
}
}
我的模型-
结构产品-
导入UIKit
结构Product:Equatable {
let name:String
var数量:Int
var price:Double
let图像名称:UIImage
// var subTotal:Double {
//返回Double(数量)*价格}
}
var productarray = [Product(名称: a,数量:5,价格:5.0,imagename:#imageLiteral(resourceName: CakeImage)),
Product(name : b,数量:10,价格:10.0,图像名称:#imageLiteral(资源名称: PeasImge)),产品(名称: a,数量:5,价格:5.0,图像名称:#imageLiteral( resourceName: vectorlogo)),
产品(名称: b,数量:10,价格:10.0,imagename:#imageLiteral(resourceName: blue)),]
class CartItem-
import Foundation
类CartItem {
var数量:Int = 1
var产品:Product
// var subTotal:Float {get {return Float(product.price)* Float(quantity)} }
init(产品:产品){
self.product =产品
}
}
类购物车-
import Foundation
类购物车{
各种项目:[ CartItem] = []
}
扩展购物车{
/ * var total:浮动{
get {return items.reduce(0.0){{value,item in
值+ item.subTotal
}
}
} * /
var totalQuantity:Int {
get {return items.reduce(0 ){值,
中的项目值+ item.quantity
}
}
}
func updateCart(with product:Product){
if!self .contains(产品:产品){
self.add(产品:产品)
}否则{
self.remove(产品:产品)
}
}
func updateCart(){
for self.items中的项目{
如果item.quantity == 0 {
updateCart(with:item.product)
}
}
}
函数add(product:Product){
let item = items.filter {$ 0.product == product}
if item.first!= nil {
item.first!.quantity + = 1
} else {
items.append(CartItem(pro管道:产品))
}
}
函数删除(产品:产品){
保护让索引= items.firstIndex(其中:{$ 0.product = = product})else {return}
items.remove(at:index)
}
func contains(product:Product)->布尔{
let item = items.filter {$ 0.product == product}
返回item.first!= nil
}
}
-
UITableViewCells-
ProductTableViewCell-
导入UIKit
协议CartDelegate {
func updateCart(cell:ProductTableViewCell)}
类ProductTableViewCell:UITableViewCell {
弱var myParent:ProductViewController?
@IBOutlet弱变量名称:UILabel!
@IBOutlet弱变量价格:UILabel!
@IBOutlet弱变量图像名称:UIImageView!
@IBOutlet弱var addToCartButton:UIButton!
var委托:CartDelegate?
覆盖函数awakeFromNib(){
super.awakeFromNib()
//初始化代码
addToCartButton.layer.cornerRadius = 5
addToCartButton.clipsToBounds = true
}
func setButton(state:Bool){
addToCartButton.isSelected =状态
addToCartButton.backgroundColor =(!addToCartButton.isSelected)吗? .black:.red
}
@IBAction func addToCart(_ sender:Any){
setButton(state:!addToCartButton.isSelected)
self.delegate? .updateCart(cell:self)
}
}
CartItemTableViewCell-
导入UIKit
协议CartItemDelegate {
func updateCartItem(cell:CartItemTableViewCell,数量:Int)
}
类CartItemTableViewCell:UITableViewCell {
@IBOutlet弱var nameLabel:UILabel!
@IBOutlet弱变量priceLabel:UILabel!
@IBOutlet弱变量增量增量:UIButton!
@IBOutlet弱var decrementButton:UIButton!
@IBOutlet弱变量数量标签:UILabel!
var委托:CartItemDelegate?
var数量:Int = 1
覆盖函数awakeFromNib(){
super.awakeFromNib()
//初始化代码
递增按钮.layer.cornerRadius = 10
增量按钮.clipsToBounds =真
decrementButton.layer.cornerRadius = 10
decrementButton.clipsToBounds =真
}
覆写func setSelected(_选择:Bool,动画:Bool){
super.setSelected(选择,动画:动画)
}
@IBAction func updateCartItemQuantity(_发送者:任意){
if(发送者!UIButton).tag == 0 {
数量=数量+ 1
}否则,如果数量> 0 {
数量=数量-1
}
decrementButton.isEnabled =数量> 0
decrementButton.backgroundColor =!decrementButton.isEnabled吗? .gray:.black
self.quantityLabel.text =字符串(描述:数量)
self.delegate?.updateCartItem(单元格:self,数量:数量)
}
}
segue已正确连接。因此,我怀疑rightBarButtonItem也就是另一个CartViewcontroller的Checkout(2)。
我已经考虑了很长时间。
我会真诚地感谢您的协助。
这是一个菜鸟错误。我给segue取了不正确的名字。在ProductViewController中,它是 showCart,而我在将
命名为 ShowCart时,即大写字母 S。这是微不足道的,但可怕!无论如何,感谢您调查我的问题。
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.
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.
这篇关于快速数据未从UIBarButtonItem传输到另一个ViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!