[英]Updating label in UITableViewCell with UIStepper in Swift
I'm a Swift beginner and I'm trying to make a simple app for ordering food.我是 Swift 初学者,我正在尝试制作一个简单的应用程序来订购食物。 The user could add a new order by setting food
name
, price
and serving
.用户可以通过设置食品
name
、 price
和serving
来添加新订单。 After adding an order, that order will be shown on the tableView as a FoodTableViewCell
, and the user could change the serving with an UIStepper called stepper
in each cell.添加订单后,该订单将作为
FoodTableViewCell
显示在 tableView 上,用户可以在每个单元格中使用名为stepper
的 UIStepper 更改服务。 Each order is a FoodItem
stored in an array called foodList
, and you can see all orders listed in a tableView in ShoppingListVC
.每个订单都是一个
FoodItem
存储在一个名为foodList
的数组中,您可以在ShoppingListVC
的 tableView 中看到列出的所有订单。
My problem is: When I press "+" or "-" button on stepper
, my servingLabel
doesn't change to corresponding value.我的问题是:当我在
stepper
上按“+”或“-”按钮时,我的servingLabel
不会更改为相应的值。 I tried to use NotificationCenter
to pass serving value to stepper
, and store new value back to food.serving
after stepperValueChanged
with delegate pattern.我尝试使用
NotificationCenter
将服务值传递给stepper
,并在stepperValueChanged
与委托模式后将新值存储回food.serving
。 However, there still seems to be some bugs.但是,似乎仍然存在一些错误。 I've been kind of confused after browsing lots of solutions on the Internet.
在网上浏览了很多解决方案后,我有点困惑。 Any help is appreciated.
任何帮助表示赞赏。
Update更新
I removed NotificationCenter
and addTarget
related methods as @Tarun Tyagi 's suggestion.我删除
NotificationCenter
和addTarget
相关的方法为@Tarun特亚吉的建议。 Now my UIStepper value turns back to 1 whereas the servingLabels are showing different numbers of serving.现在我的 UIStepper 值变回 1,而servingLabels 显示不同数量的服务。 Since NotificationCenter doesn't help, how can I connect the label and stepper value together?
由于 NotificationCenter 没有帮助,我如何将标签和步进值连接在一起? Is it recommended to implement another delegate?
是否建议实施另一个委托?
Here are my codes(Updated on July 8):这是我的代码(7月8日更新):
FoodItem食品项目
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
}
}
ViewController视图控制器
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)
}
}
Cell Config:单元配置:
protocol FoodTableViewCellDelegate: AnyObject {
func stepper(sender: FoodTableViewCell)
}
@IBAction func stepperButtonTapped(sender: UIStepper) {
delegate?.stepperButton(sender: self)
stepperLabel.text = "\(Int(countStepper.value))"
}
Controller Config:控制器配置:
cellForRow:单元格:
cell.countStepper.value = Double(foodList[indexPath.row].serving);
cell.stepperLabel.text = "\(Int(cell.countStepper.value))"
Delegate Method:委托方式:
func stepperButton(sender: FoodTableViewCell) {
if let indexPath = tableView.indexPath(for: sender){
print(indexPath)
foodList[sender.tag].serving = Int(sender.countStepper.value)
}
}
Initially FoodTableViewCell
is the ONLY target for UIStepper
value changed (looking at @IBAction
inside FoodTableViewCell
).最初
FoodTableViewCell
是UIStepper
值更改的唯一目标(查看@IBAction
FoodTableViewCell
)。
When you dequeue a cell to display on screen, you call -当您将单元格出列以在屏幕上显示时,您调用 -
cell.stepper.addTarget(self, action: #selector(stepperValueChanged(_:)), for: .valueChanged)
which causes your ShoppingListVC
instance to be added as an additional target every time a cellForRow
call is executed.这会导致每次执行
cellForRow
调用时将您的ShoppingListVC
实例添加为附加目标。
Things to fix :需要解决的问题:
NotificationCenter
related code from both classes.NotificationCenter
相关的代码。cell.stepper.addTarget()
line as well.cell.stepper.addTarget()
行。 This would give you a better idea of why it is happening this way.这会让您更好地了解为什么会以这种方式发生。 Update your question with these changes in case you still don't have what you want.
如果您仍然没有想要的东西,请使用这些更改更新您的问题。
// Inside cellForRow
cell.stepper.value = food.serving
Please check value stepper pod it will help you: Value stepper请检查 value stepper pod 它将帮助您: Value stepper
Integrate value stepper pod and use below code for basic implementation.集成 value stepper pod 并使用以下代码进行基本实现。
import ValueStepper
let valueStepper: ValueStepper = {
let stepper = ValueStepper()
stepper.tintColor = .whiteColor()
stepper.minimumValue = 0
stepper.maximumValue = 1000
stepper.stepValue = 100
return stepper
}()
override func viewDidLoad() {
super.viewDidLoad()
valueStepper.addTarget(self, action: "valueChanged:", forControlEvents: .ValueChanged)
}
@IBAction func valueChanged1(sender: ValueStepper) {
// Use sender.value to do whatever you want
}
Its simplify custom stepper implantation.Take outlet of value stepper view in table tableview and use it.它简化了自定义步进器植入。在表格tableview中取出值步进器视图并使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.