gpt4 book ai didi

ios - 如何防止单元格在另一个单元格中镜像按钮按下操作?

转载 作者:行者123 更新时间:2023-11-28 13:24:35 25 4
gpt4 key购买 nike

I have 3 buttons in the cells of my tableview, they buttons are in a @IBAction button collection so when one is selected it turns the button color from blue to red and deselects the button previously pressed to back to blue.执行这些操作时代码工作正常

我遇到的问题是,当在一个单元格中选择一个按钮时,将在另一个单元格中选择完全相同的按钮,如下所示▼

到目前为止,我尝试的方法不起作用,我认为可能起作用的是我在 View Controller 中创建一个“@objc func”,但我不知道从我创建的内容中去哪里以防止单元格中的“镜像”

我知道我接近解决方案
提前感谢您提供的任何帮助

How to update UILabel on a button click in UITableViewCell in swift 4 and xcode 9?

cell image

import UIKit

class Cell: UITableViewCell {

@IBOutlet weak var lbl1: UILabel!
@IBOutlet weak var lbl2: UILabel!
@IBOutlet weak var lbl3: UILabel!

@IBOutlet weak var btn1: RoundButton!
@IBOutlet weak var btn2: RoundButton!
@IBOutlet weak var btn3: RoundButton!

var lastSelectedButton = UIButton()
@IBAction func cartTypeSelected(_ sender: RoundButton) {
lastSelectedButton.isSelected = false; do {
self.lastSelectedButton.backgroundColor = UIcolor.blue
} //Plus any deselect logic for this button
lastSelectedButton = sender //If any buttons are not affect by this selection logic exclude them here
sender.isSelected = true; do {
self.lastSelectedButton.backgroundColor = UIColor.red
}
}
}
import UIKit

class ViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

tableView.dataSource = self
tableView.delegate = self

}
var lastSelectedButton = UIButton()
@objc func selectedButton(_ sender: RoundButton) {
lastSelectedButton.isSelected = false; do {
self.lastSelectedButton.backgroundColor = UIcolor.blue
} //Plus any deselect logic for this button
lastSelectedButton = sender
sender.isSelected = true; do {
self.lastSelectedButton.backgroundColor = UIColor.red
}
}
}

extension View[![enter image description here][1]][1]Controller: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else { return UITableViewCell() }

return cell
}
}

最佳答案

你好,伊芙琳!使用委托(delegate)模式! :)

这里有一些解释可以帮助你继续前进:

  • 创建一个模型来表示您的表格 View 内容


  • 我们可以使用什么样的模型来表示只选择一个按钮的状态?枚举可以表示(将其添加到单独的文件或 Controller 中):
    enum ButtonSelectionIdentity {
    case first
    case second
    case third
    }

    我们的 TableView 将显示这些枚举的数组,在 Controller 中,让我们添加一个实例变量来保存数据,并用一个空数组初始化它:
    private var elements: [ButtonSelectionIdentity] = []

    让我们用 100 个元素填充这个数组,默认选择第一个按钮,在 Controller viewDidLoad 函数中,添加:
        for i in 0..<100 {
    elements.append(ButtonSelectionIdentity.first)
    }
  • 确保从模型
  • 更新单元格


    所以现在我们有一个模型( ButtonSelectionIdentity 的数组),我们希望 TableView Controller 反射(reflect)该模型。为此,我们改变了 Controller 如何符合 UITableViewDataSource 的原始方式。 .我们需要新的实现来从数组中获取数据:
    extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return elements.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else {
    return UITableViewCell()
    }

    let model = elements[indexPath.row]
    cell.update(with: model)

    return cell
    }
    }

    是的,经过上述更改后,它不会编译,直到我们向单元类添加更新方法:
    func update(with model: ButtonSelectionIdentity) {
    btn1.backgroundColor = .blue
    btn2.backgroundColor = .blue
    btn3.backgroundColor = .blue

    switch model {
    case .first:
    btn1.backgroundColor = .red
    case .second:
    btn2.backgroundColor = .red
    case .third:
    btn3.backgroundColor = .red
    }
    }

    编译并运行,你应该看到 100 个单元格的第一个正方形是红色的。
  • 让我们将单元格操作连接到 Controller


  • 删除 buttonSelected Controller 类中的方法,并删除您的 btnTypeSelected您的 Cell 类的方法,以便我们可以重新开始。

    在这个阶段,我们有一个元素数组,它们显示在 Controller 内部的表格 View 中。 Controller 拥有它,因为它创建了它。单元格仅用于呈现 Controller 所具有的状态。因此,为了让我们的单元格更新,我们需要告诉 Controller 我们正在更新。为此,我们可以使用委托(delegate)模式。让我们创建一个单元委托(delegate)协议(protocol)来描述它。

    在您的 Cell类文件,在 class Cell ... 之前, 添加:
    protocol CellDelegate: class {
    func onCellModelChange(cell: Cell, model: ButtonSelectionIdentity)
    }

    所以这是我们将用来让 Controller 知道单元格中状态变化的委托(delegate)。让我们向委托(delegate)添加对单元格的弱引用。在您的 Cell , 添加:
    weak var delegate: CellDelegate?

    现在,使您的 Controller 符合 CellDelegate协议(protocol)。在您的 Controller 类中,添加:
    extension ViewController: CellDelegate {
    func onCellModelChange(cell: Cell, model: ButtonSelectionIdentity) {
    }
    }

    现在我们将其留空,稍后再完成。

    现在, Controller 可以是单元格的代表。让它成为一个!
    更新 cellForRowAt您的 Controller 的方法,如下所示:
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else {
    return UITableViewCell()
    }

    let model = elements[indexPath.row]
    cell.update(with: model)
    cell.delegate = self

    return cell
    }

    完成,我们将 Controller 配置为单元格的代表!让我们利用它!
  • 使 Controller 更新模型,当单元报告它的状态变化时


  • 在您的单元格中,分别连接每个按钮上的 IBActions:
    @IBAction func onFirstButtonTapped(_ sender: RoundButton) {
    }

    @IBAction func onSecondButtonTapped(_ sender: RoundButton) {
    }

    @IBAction func onThirdButtonTapped(_ sender: RoundButton) {
    }

    每当点击按钮时,我们希望我们的单元格告诉 Controller 状态更改,例如:
    @IBAction func onFirstButtonTapped(_ sender: RoundButton) {
    delegate?.onCellModelChange(cell: self, model: .first)
    }

    相应地实现其他两种方法。

    在您的 Controller 中,让我们重新访问 onCellModelChange方法。现在单元格上发生了一个 Action ,我们需要在 elements 中找到一个元素。数组,对应于该单元格。为此,我们可以使用 tableView -s -indexPath(for:)方法:
    extension ViewController: CellDelegate {
    func onCellModelChange(cell: Cell, model: ButtonSelectionIdentity) {
    guard let indexPath = tableView.indexPath(for: cell) else {
    return
    }
    print(indexPath)
    }
    }

    如果您运行该应用程序,在此阶段您应该会看到与您按下按钮的单元格相对应的索引路径的日志。
    还不是我们需要的。

    我们的表格 View 只呈现一个部分,因此我们可以忽略索引路径中的部分,只考虑一行,这将与我们的元素索引相同。让我们使用这个索引更新数组中的值:
    extension ViewController: CellDelegate {
    func onCellModelChange(cell: Cell, model: ButtonSelectionIdentity) {
    guard let indexPath = tableView.indexPath(for: cell) else {
    return
    }
    let index = indexPath.row
    elemets[index] = model
    }
    }

    现在,如果您运行它,您应该更新模型,但单元格的状态不会立即更新。如果您将单元格滚动到屏幕外,然后再次向后滚动,您仍然可以看到它正在工作。

    最后一点是立即更新单元格。我们怎么能做到这一点?让我们将更新的模型放回单元格:
    extension ViewController: CellDelegate {
    func onCellModelChange(cell: Cell, model: ButtonSelectionIdentity) {
    guard let indexPath = tableView.indexPath(for: cell) else {
    return
    }
    let index = indexPath.row
    elemets[index] = model
    cell.update(with: model)
    }
    }

    这应该是它!
    我没有测试它也没有编译它:)所以如果你发现任何错别字,请告诉我:)
    干杯

    关于ios - 如何防止单元格在另一个单元格中镜像按钮按下操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609360/

    25 4 0
    文章推荐: css - 使用 css 减少
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com