【发布时间】:2021-09-18 00:51:27
【问题描述】:
我是 Swift 初学者,我正在尝试制作一个简单的点餐应用。用户可以通过设置食物name、price和serving来添加新订单。添加订单后,该订单将在 tableView 上显示为FoodTableViewCell,用户可以在每个单元格中使用名为stepper 的 UIStepper 更改服务。每个订单都是一个FoodItem,存储在一个名为foodList 的数组中,您可以在ShoppingListVC 的tableView 中查看所有订单。
我的问题是:当我按下stepper 上的“+”或“-”按钮时,我的servingLabel 不会更改为相应的值。我尝试使用NotificationCenter 来将服务值传递给stepper,并在stepperValueChanged 之后使用委托模式将新值存储回food.serving。但是,似乎仍然存在一些错误。在网上浏览了很多解决方案后,我有点困惑。任何帮助表示赞赏。
更新
根据@Tarun Tyagi 的建议,我删除了NotificationCenter 和addTarget 相关的方法。现在我的 UIStepper 值变回 1,而 servingLabels 显示不同数量的服务。由于 NotificationCenter 没有帮助,我如何将标签和步进值连接在一起?是否建议实现另一个委托?
这是我的代码(7 月 8 日更新):
食品
class FoodItem: Equatable {
static func == (lhs: FoodItem, rhs: FoodItem) -> Bool {
return lhs === rhs
}
var name: String
var price: Int
var serving: Int
var foodID: String
init(name: String, price: Int, serving: Int) {
self.name = name
self.price = price
self.serving = serving
self.foodID = UUID().uuidString
}
}
视图控制器
import UIKit
class ShoppingListVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
var foodList = [FoodItem]()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
...
for i in 1...5 {
let testItem = FoodItem(name: "Food\(i)", price: Int.random(in: 60...100), serving: Int.random(in: 1...10))
self.foodList.append(testItem)
}
}
// MARK: - Table view data source
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "foodCell", for: indexPath) as! FoodTableViewCell
let food = foodList[indexPath.row]
cell.nameLabel.text = food.name
cell.priceLabel.text = "$\(String(food.price)) / serving"
cell.servingLabel.text = "\(String(food.serving)) serving"
cell.stepper.tag = indexPath.row
cell.delegate = self
return cell
}
}
// MARK: - FoodTableViewCellDelegate Method.
extension ShoppingListVC: FoodTableViewCellDelegate {
func stepper(_ stepper: UIStepper, at index: Int, didChangeValueTo newValue: Double) {
let indexPath = IndexPath(item: index, section: 0)
guard let cell = tableView.cellForRow(at: indexPath) as? FoodTableViewCell else { return }
let foodToBeUpdated = foodList[indexPath.row]
print("foodToBeUpdated.serving: \(foodToBeUpdated.serving)")
foodToBeUpdated.serving = Int(newValue)
print("Value changed in VC: \(newValue)")
cell.servingLabel.text = "\(String(format: "%.0f", newValue)) serving"
}
}
TableViewCell
import UIKit
protocol FoodTableViewCellDelegate: AnyObject {
func stepper(_ stepper: UIStepper, at index: Int, didChangeValueTo newValue: Double)
}
class FoodTableViewCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var priceLabel: UILabel!
@IBOutlet weak var servingLabel: UILabel!
@IBOutlet weak var stepper: UIStepper!
weak var delegate: FoodTableViewCellDelegate?
@IBAction func stepperValueChanged(_ sender: UIStepper) {
sender.minimumValue = 1
servingLabel.text = "\(String(format: "%.0f", sender.value)) serving"
// Pass the new value to ShoppingListVC and notify which cell to update using tag.
print("sender.value: \(sender.value)")
delegate?.stepper(stepper, at: stepper.tag, didChangeValueTo: sender.value)
}
override func awakeFromNib() {
super.awakeFromNib()
print(stepper.value)
}
}
【问题讨论】:
标签: ios swift xcode uitableview uistepper