TableView单元格的数据在滚动时重置

本文关键字:滚动 单元格 数据 TableView | 更新日期: 2023-09-27 18:02:31

-----编辑-----

通过在TableViewSource中使用DraggingStarted方法,我找到了解决问题的方法。这不是最理想的解决方案,我会继续寻找合适的方法来处理我的问题,但现在,我可以继续我的过程。

public override void DraggingStarted(UIScrollView scrollView)
{
    for (int i = 0; i < 12; i++)
    {
        try
        {
            GlobalSupport.NewClientData[i] = ((scrollView as UITableView).CellAt(NSIndexPath.FromItemSection(i, 0)).ContentView.Subviews[1] as UITextField).Text;
        }
        catch
        {
        }
    }
    Console.WriteLine("hoi");
}

在我的GetCell方法中,我搜索这个新的数据结构,以找到正确的值:

if (GlobalSupport.NewClientData[indexPath.Row] != "")
{
    cell.cellValue = GlobalSupport.NewClientData[indexPath.Row];
}

-----ENDEDIT----

我正在致力于实现一个以TableView为中心的应用程序。这意味着我的大多数屏幕都是TableViews,其中有可重复使用的单元格。这些单元格是使用Xcode设计器定义的(这意味着我在资源中为每个不同的唯一单元格都有一个.cs、一个.xib和一个.Designer(。

当用预定义的数据(自定义数据对象、字典、列表等(构建TableView时,我调用单元格的.cs中的方法来修改.xib中定义的两个UILabel(或一个UILabel和一个UIImageView(。这一切都很顺利;提供的数据通过TableViewSource中的GetCell方法被放入标签和其他控件中,即使在滚动后也会保持在那里(因为数据是预定义的,并使用IndexPath.Row来确定放置位置(。

现在麻烦来了:

我有另一个单元格,其中有一个UILabel和UITextField。UILabel的文本已修改为与我的可本地化字符串文件相对应。在我的GetCell方法中,在我的TableViewSource中,有一个开关,看起来像这样:

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
    CTextInput cell = (CTextInput)tableView.DequeueReusableCell(CTextInput.Identifier);
    switch (indexPath.Row)
    {
        case 0:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtBSN", "", "");
            break;
        case 1:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtPrefix", "", "");
            break;
        case 2:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtInitials", "", "");
            break;
        case 3:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtFirstName", "", "");
            break;
        case 4:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtLastName", "", "");
            break;
        case 5:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtDateOfBirth", "", "");
            cell.Accessory = UITableViewCellAccessory.DetailDisclosureButton;
            break;
        case 6:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtCity", "", "");
            break;
        case 7:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtStreet", "", "");
            break;
        case 8:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtHouseNumber", "", "");
            break;
        case 9:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtZipcode", "", "");
            break;
        case 10:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtCountry", "", "");
            break;
        case 11:
            cell.cellLabel = NSBundle.MainBundle.LocalizedString("txtPhonenumber", "", "");
            break;
        default:
            break;
    }
    return cell;
}

这很管用。

现在,当加载视图时,用户可以在每个UILabels旁边的UITextField中输入他或她的数据。提供数据,当用户在TableView中向下移动时,所有文本都会停留在那里。。。直到用户到达屏幕底部,需要滚动查看其他单元格。然后,在前几个单元格的UITextField中提供的数据被重置为单元格的.xib文件中指定的值,即"。这是因为在我的GetCell方法的开头使用了DequeueReusableCell。每次有新单元格进入用户视图时,都会调用GetCell方法。这意味着所有从用户视图中消失的单元格都将重置为默认值。

提供数据

向下滚动

向上滚动

我不想为这个视图中的每个单元格单独设置一组.cs、.xib和.designer文件,而且目前还没有找到保存单元格UITextField内容的方法。更重要的是,我需要每个单元格中UITextField的内容,以便创建一个新的对象,我需要进一步推进这个过程。

非常感谢在这个问题上的任何帮助。如果您需要更多信息,请随时联系我!

尊敬的各位:,比约恩

TableView单元格的数据在滚动时重置

UITableView的DataSource需要为单元格提供完整、正确呈现所需的任何数据。由于单元格是重复使用的,它们可以被认为是"愚蠢的",并且完全依赖于数据源来知道要显示什么。

记住这一点,您需要做的是更新DataSource,以包括输入到单元格的UITextField中的任何内容。

以下是如何实现这一目标的示例:

1.(将UITableView的数据源实现为键/值对:

DataSource = new Dictionary<string, string> () {
    { "Label 1", string.Empty },
    { "Label 2", string.Empty },
    ...
    ...
};

对于您的场景,"标签1"将是NSBundle.MainBundle.LocalizedString("txtBSN", "", "")

2.(像这样实现CTextInput单元:

public partial class CTextInput : UITableViewCell
{
    Action<string, string> OnTextFieldTextChanged;
    public CustomCell ()
    {
    }
    public CustomCell (IntPtr handle) : base (handle)
    {
    }
    public void SetupCell (string labelText, string value, Action<string, string> onTextFieldTextChanged)
    {
        CellLabel.Text = labelText;
        CellTextField.Text = value;
        OnTextFieldTextChanged = onTextFieldTextChanged;
        CellTextField.EditingDidEnd += HandleEditingDidEnd;
    }
    void HandleEditingDidEnd (object sender, EventArgs e)
    {
        var textField = sender as UITextField;
        OnTextFieldTextChanged (CellLabel.Text, textField.Text);
    }
    // clean up
    public override void PrepareForReuse ()
    {
        base.PrepareForReuse ();
        OnTextFieldTextChanged = null;
        CellTextField.EditingDidEnd -= HandleEditingDidEnd;
    }
    protected override void Dispose (bool disposing)
    {
        if (disposing) {
            OnTextFieldTextChanged = null;
        }
        base.Dispose (disposing);
    }
}

这里的重要内容是SetupCell方法和HandleEditingDidEnd事件处理程序。挂接UITextField的EditingDidEnd,以便可以调用传入的onTextFieldTextChanged操作。

3.(添加一个OnTextFieldTextChange处理程序并在视图控制器中实现GetCell方法,如下所示:

public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell ("CellIdentifier")  as CTextInput ?? new CTextInput ();
    var labelText = DataSource.Keys.ElementAt (indexPath.Row);
    var textFieldText = DataSource.Values.ElementAt (indexPath.Row);
    cell.SetupCell (labelText, textFieldText, OnTextFieldTextChange);
    return cell;
}

public void OnTextFieldTextChange (string key, string value)
{
    if (DataSource.ContainsKey (key)) {
        DataSource [key] = value;
    }
}

在这里,您定义了一个OnTextFieldTextChange方法,该方法可以为CTextInput类中先前定义的SetupCell方法中的Action<string, string> onTextFieldTextChanged参数传入。

OnTextFieldTextChange方法中,您所做的只是更新DataSource中给定键的值。

现在,当UITextField发出EditingDidEnd事件时,数据源将更新为包括用户输入的值。

希望这能有所帮助!