Я новичок в Swift и пытаюсь сделать простое приложение для заказа еды. Пользователь может добавить новый заказ, установив продукты name
, price
и serving
. После добавления заказа этот заказ будет отображаться в tableView как FoodTableViewCell
, и пользователь может изменить обслуживание с помощью UIStepper с именем stepper
в каждой ячейке. Каждый заказ представляет собой FoodItem
, хранящийся в массиве с именем foodList
, и вы можете увидеть все заказы, перечисленные в tableView, в ShoppingListVC
.
Моя проблема: Когда я нажимаю кнопку + или - на stepper
, мое servingLabel
не меняется на соответствующее значение. Я пытался использовать NotificationCenter
, чтобы передать значение обслуживания в stepper
и сохранить новое значение обратно в food.serving
после stepperValueChanged
с шаблоном делегата. Тем не менее, кажется, что все еще есть некоторые ошибки. Я немного запутался после просмотра множества решений в Интернете. Любая помощь приветствуется.
Обновить
Я удалил методы, связанные с NotificationCenter
и addTarget
, как предложил @Tarun Tyagi. Теперь мое значение UIStepper возвращается к 1, тогда как serveLabels показывает разные количества обслуживания. Поскольку NotificationCenter не помогает, как я могу связать метку и значение шагового двигателя вместе? Рекомендуется ли реализовать еще один делегат?
Вот мои коды (обновлено 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)
}
}