我的 TableView 单元格有一个按钮。单击时,我想展开单元格。为了扩展,我在单击按钮时更改单元格的高度并重新加载行。但是,当扩展一行然后我尝试扩展另一行时,行为并不符合预期。先前展开的行将关闭,而不是单击的行。
此外,有时我必须单击按钮两次才能展开。
public class ProgramMeasurementDetailsTableViewSource : UITableViewSource
{
List<ProgramMeasurementDetail> mList;
string HeaderIdentfier = "programMeasurementDetailsHeader";
string CellIdentifier = "programMeasurementDetailsCell";
int TAG_CHECKBOX = 61;
int TAG_LABEL_VITAL_NAME = 62;
int TAG_LABEL_GOAL = 63;
int TAG_BUTTON_EDIT = 64;
int TAG_VIEW_HEADER_COLUMN_SEPARATOR = 66;
int TAG_VIEW_ROW_COLUMN_SEPARATOR = 65;
List<bool> expandStatusList = new List<bool>();
UITableView tableView;
public ProgramMeasurementDetailsTableViewSource(List<ProgramMeasurementDetail> mList, UITableView tableView)
{
this.tableView = tableView;
this.mList = mList;
for (int i = 0; i < mList.Count; i++)
expandStatusList.Add(false);
}
public override nint NumberOfSections(UITableView tableView)
{
return 1;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return mList.Count;
}
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
{
return 32;
}
public override nfloat GetHeightForRow(UITableView tableView, Foundation.NSIndexPath indexPath)
{
if (expandStatusList[indexPath.Row])
return 70;
else
return 32;
}
public override UITableViewCell GetCell(UITableView tableView, Foundation.NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
if (cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier);
}
CheckBox checkBox = (CheckBox)cell.ViewWithTag(TAG_CHECKBOX);
UILabel vitalNameLabel = (UILabel)cell.ViewWithTag(TAG_LABEL_VITAL_NAME);
UILabel goalLabel = (UILabel)cell.ViewWithTag(TAG_LABEL_GOAL);
UIButton editGoalButton = (UIButton)cell.ViewWithTag(TAG_BUTTON_EDIT);
editGoalButton.TouchUpInside += (object sender, EventArgs e) =>
{
expandStatusList[indexPath.Row] = !expandStatusList[indexPath.Row];
tableView.ReloadRows(new Foundation.NSIndexPath[] { indexPath }, UITableViewRowAnimation.Automatic);
};
.....
return cell;
}
}
我尝试将按钮单击事件处理移到 if (cell == null) 内,但是按钮单击/展开根本不起作用。我设置了断点,似乎该部分永远不会被执行。
我在 Storyboard中设计了单元布局。
我已经为这个问题苦苦挣扎了一段时间了。如有任何帮助,我们将不胜感激。
最佳答案
当您上下滚动列表时,您看到的错误是否会发生?发生这种情况是因为您在 GetCell
方法中连接了 TouchUpInside
事件处理程序,然后当单元格被重用时它永远不会被取消 Hook ,因此您最终会连接多个单元格到同一个处理程序甚至多个处理程序!
一般来说,您不想对 GetCell
方法中的内容执行这些类型,它应该仅用于 DequeueReusableCell
或创建一个新的。其他所有事情都应该在自定义单元内完成。
查看您的代码示例,您似乎没有使用自定义单元格,因此您可以执行以下操作:
1.) 在GetCell
中将按钮的标签设置为IndexPath的行
editGoalButton.Tag = indexPath.Row;
2.) 在 ProgramMeasurementDetailsTableViewSource
中为您的事件处理程序创建一个单独的方法:
private void ToggleRow(object sender, EventArgs e)
{
var btn = sender as UIButton;
expandStatusList[btn.Tag] = !expandStatusList[btn.Tag];
tableView.ReloadRows(new Foundation.NSIndexPath[] { NSIndexPath.FromRowSection(btn.Tag, 0) }, UITableViewRowAnimation.Automatic);
}
3.) 在重新 Hook TouchUpInside
处理程序之前,在 GetCell
中取消 Hook :
editGoalButton.TouchUpInside -= ToggleRow;
editGoalButton.TouchUpInside += ToggleRow;
虽然这将确保按钮仅连接一次,但这确实不是处理此类情况的正确方法。您应该使用自定义单元格并在单元格中进行所有接线,然后在 UITableViewCell
中的 PrepareForReuse
覆盖中进行脱钩和清理。我强烈建议您阅读此Xamarin tutorial
如果您确实经历过它...请注意 GetCell
方法是多么的统一。
--更新--
在您的 CustomCell
类中:
private EventHandler _tapAction;
public void Setup(EventHandler tapAction, int row, ....)
{
//keep a reference to the action, so we can unhook it later
_tapAction = tapAction;
editGoalButton.Tag = row;
....
editGoalButton.TouchUpInside += _tapAction;
}
public override void PrepareForReuse()
{
....
editGoalButton.TouchUpInside -= _tapAction;
_tapAction = null;
}
当您在 GetCell
中调用 Setup
时,只需传递 ToggleRow
方法作为 Action 参数即可。
关于ios:UITableVIewCell 扩展未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38961804/