gpt4 book ai didi

ios - 在 UITableView 的自定义 Prototype Cell 中,UITextField 值替换为其他 Prototype Cell

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:55:55 26 4
gpt4 key购买 nike

我使用了一个 UITableView 并在其中使用了 2 个 prototype 单元格,现在在那些原型(prototype)单元格中,我使用了 1 个 UITextField .

现在,当我运行应用程序并在第一个原型(prototype)单元格中输入值时,我滚动 UITableView,然后第一个原型(prototype)单元格的文本字段值变为最后一个原型(prototype)单元格的文本字段值。所以每次我向下滚动或向上滚动时它都会替换。有时它会变成空白。

这是我的代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0)
{

Client_MobileCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier_MobileCell forIndexPath:indexPath];
cell.lblTitle.text = [arrTitle objectAtIndex:indexPath.row];
cell.txtMobile.placeholder = [arrPlaceholder objectAtIndex:indexPath.row];
// cell.txtMobile.tag = indexPath.row+100;
return cell;
}
else
{
// Client_Common_Cell *cell = (Client_Common_Cell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier_CommonCell forIndexPath:indexPath];
Client_Common_Cell *cell = (Client_Common_Cell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier_CommonCell];

// cell.txtCommon.tag = indexPath.row+100;
cell.delegate = self;

if(indexPath.row == 1 || indexPath.row == 2 || indexPath.row == 3 || indexPath.row == 4){
if(indexPath.row == 2)
cell.txtCommon.secureTextEntry = YES;
else if(indexPath.row == 4){
cell.txtCommon.keyboardType = UIKeyboardTypeEmailAddress;
}
cell.imgArrow.hidden = YES;
cell.btnSelection.hidden = YES;
}
else{
cell.btnSelection.hidden = NO;
cell.imgArrow.hidden = NO;
}
cell.lblTitle.text = [arrTitle objectAtIndex:indexPath.row];
cell.txtCommon.placeholder = [arrPlaceholder objectAtIndex:indexPath.row];
return cell;
}

最佳答案

TL;DR(给我代码)

Github 链接:https://github.com/starkindustries/CustomTableView

问题

正如其他人所指出的,dequeueReusableCellWithIdentifier 将在滚动时重复使用相同的单元格引用。请查看下面的 gif 动图,以直观地演示此问题。

gif 中的表格有 20 行(多于屏幕显示的行数)。每行都有一个文本字段。我分别在第一到第四行输入了“一”、“二”、“三”、“四”。

如您所见,当我向下滚动时,“二”、“三”和“一”神奇地出现在底部(不需要的行为)。这是因为当滚动到屏幕外时,这些单元格从顶部出队,并在底部再次使用。

enter image description here

讨论

在对网络和堆栈溢出进行大量研究后,我建议您在文本字段发生变化时将其值存储在数组中。然后您可以在 cellForRowAt 方法中相应地设置文本字段文本。 @Rob 在他的回答中完美地解释了如何使用模型- View - Controller 模式解决这个问题:https://stackoverflow.com/a/38272077/2179970 .我已将他的建议实现到以下示例中。

工作原理

  1. 首先,您将设置一个协议(protocol),以便自定义 UITableViewCell( View )可以发送一个消息返回给 ViewController 以通知它它的文本字段变了。 ViewController 将实现该协议(protocol)。单元将调用协议(protocol)方法。
  2. 您的应用程序的用户将输入文本。这将触发textFieldDidChange(_:) 在自定义 UITableViewCell 类中。
  3. textFieldDidChange(_:) 将调用 TableViewController 的委托(delegate)方法 cell(cell: UITableViewCell, updatedCustomTextField
    textField: UITextField)
    通知 Controller 它是文本变了。
  4. Controller 将更新其文本数组(模型)以保存改变。
  5. cellForRowAt 将更新单元格的文本字段如果需要重复使用,则内容适当。

解决方案

协议(protocol):

// Protocol from Step 1
protocol CustomCellDelegate: class {
// This is the function that the ViewController will implement
func cell(cell: UITableViewCell, updatedCustomTextField textField: UITextField)
}

自定义 UITableViewCell:

class MyTableViewCell: UITableViewCell, UITextFieldDelegate {
// Protocol reference (Step 1)
weak var delegate: CustomCellDelegate?
@IBOutlet weak var textField: UITextField!

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
// (Step 2) Add a "textFieldDidChange" notification method to the text field control.
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: UIControlEvents.editingChanged)
}

// Step 2
func textFieldDidChange(_ textField: UITextField) {
delegate?.cell(cell: self, updatedCustomTextField: textField)
}

override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}

}

View Controller :

class MyTableViewController: UITableViewController, CustomCellDelegate {

var myTexts: [String?]!

override func viewDidLoad() {
super.viewDidLoad()

myTexts = Array(repeating: nil, count: 20)

let nib = UINib(nibName: "MyTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "MyTableViewCell")
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("CellForRowAt: " + indexPath.row.description)
let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath) as! MyTableViewCell
// Step 5: TableView updates cell contents if reused
cell.delegate = self
cell.textField.text = myTexts[indexPath.row]
return cell
}

// MARK: - CustomCellDelegate Method
// Step 3: The cell will call this protocol method to message the controller
func cell(cell: UITableViewCell, updatedCustomTextField textField: UITextField) {
// when the cell tells us that its text field's value changed, update our own model
if let indexPath = tableView.indexPath(for: cell), let string = textField.text {
// Step 4: The controller updates the model:
print("delegate method cell updatedCustomTextField")
myTexts[indexPath.row] = string
}
}
}

结果

我像以前一样在前四行中输入了相同的“一”、“二”、“三”、“四”。这一次,表格的行为符合预期:文本字段内容出现在我放置它们的位置,它们不会随机消失/出现。

enter image description here

Github 链接

这是项目的链接:https://github.com/starkindustries/CustomTableView

引用资料

Init custom UITableViewCell from nib without dequeueReusableCellWithIdentifier

UITextFields in UITableView, entered values reappearing in other cells

UITextField in UITableViewCell and validation in modal view

关于ios - 在 UITableView 的自定义 Prototype Cell 中,UITextField 值替换为其他 Prototype Cell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37652121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com