Xamarin iOS UITableView在初始设置上调用所有单元的委托方法,而不仅仅是可见单元

时间:2019-02-21 13:34:46

标签: c# ios uitableview xamarin xamarin.ios

我有一个带有自定义单元格的UITableView。此TableView在视图控制器中,并占据视图的完整尺寸。每个单元格的RowHeight都设置为TableView的高度,因此每个单元格都占据了全屏(减去导航栏)。这是该设置的屏幕截图。 Red是我的自定义单元格;向下滑动将翻到下一个颜色不同的下一个页面:

UITableView Cell

当TableView首先在屏幕上可见时,我将模型(一组颜色)传递给Setup方法,然后该方法设置了Delegates。在此初始设置期间,尽管每次仅一个单元可见,但{em>每个单元都调用了GetCell委托的UITableViewDataSource方法。然后,这会触发WillDisplay类的CellDisplayingEndedUITableViewDelegate委托方法。

给我的印象是UITableView仅会根据需要(在可见时)创建每个单元的实例,但是似乎正在为负载中的每个单元创建一个实例,而与可见性无关。

我创建了一个精简样本以共享,该样本具有该表的6条记录。然后,在上述每个委托方法的开头添加一个日志,这是设置TableView时的输出:

[0:] GetCell called. Row 0
[0:] WillDisplayCell called. Row 0, RowHeight 672
[0:] GetCell called. Row 1
[0:] WillDisplayCell called. Row 1, RowHeight 672
[0:] GetCell called. Row 2
[0:] WillDisplayCell called. Row 2, RowHeight 672
[0:] GetCell called. Row 3
[0:] WillDisplayCell called. Row 3, RowHeight 672
[0:] GetCell called. Row 4
[0:] WillDisplayCell called. Row 4, RowHeight 672
[0:] GetCell called. Row 5
[0:] WillDisplayCell called. Row 5, RowHeight 672
[0:] CellDisplayingEnded called. Row 1, RowHeight: 672
[0:] CellDisplayingEnded called. Row 2, RowHeight: 672
[0:] CellDisplayingEnded called. Row 3, RowHeight: 672
[0:] CellDisplayingEnded called. Row 4, RowHeight: 672
[0:] CellDisplayingEnded called. Row 5, RowHeight: 672

如前所述,一次只能在屏幕上看到一个单元格。为什么最初创建所有6个单元格?

示例代码

public class SampleCell : UITableViewCell {
    public void Setup(UIColor color) {
        BackgroundColor = color;
    }
}

public class SampleTableViewDataSourceDelegate : UITableViewDataSource {
    public SampleTableViewDataSourceDelegate(UIColor[] model) {
        this.model = model;
    }

    private readonly UIColor[] model;

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) {
        Debug.WriteLine($"GetCell called. Row {indexPath.Row}");
        var reuseIdentifier = "SampleCell";

        var cell = tableView.DequeueReusableCell(reuseIdentifier) as SampleCell;

        cell = (cell ?? (cell = new SampleCell()));

        cell.Setup(model[indexPath.Row]);

        return cell;
    }

    public override nint NumberOfSections(UITableView tableView) {
        return 1;
    }

    public override nint RowsInSection(UITableView tableView, nint section) {
        return model.Length;
    }
}

public class SampleTableViewDelegate : UITableViewDelegate {
    public SampleTableViewDelegate(UIColor[] model) {
        this.model = model;
    }

    private readonly UIColor[] model;

    public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath) {
        Debug.WriteLine($"WillDisplayCell called. Row {indexPath.Row}, RowHeight {tableView.RowHeight}");
    }

    public override void CellDisplayingEnded(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath) {
        Debug.WriteLine($"CellDisplayingEnded called. Row {indexPath.Row}, RowHeight: {tableView.RowHeight}");
    }
}

public partial class SampleTableView : TableViewBase {
    public SampleTableView(IntPtr handle) : base(handle) {
        PagingEnabled = true;
    }

    private UIColor[] model;

    public void Setup(UIColor[] model) {
        this.model = model;

        Delegate = new SampleTableViewDelegate(model);
        DataSource = new SampleTableViewDataSourceDelegate(model);
    }
}

然后,在我的ViewController中,按照以下方式传递模型:

public override void ViewDidLoad() {
    base.ViewDidLoad();

    var model = new UIColor[] {
        UIColor.Green,
        UIColor.Red,
        UIColor.Magenta,
        UIColor.Cyan,
        UIColor.Blue,
        UIColor.Purple
    };

    SampleTableView.RowHeight = SampleTableView.Frame.Height;
    SampleTableView.Setup(model);
}

1 个答案:

答案 0 :(得分:0)

哦,法律规定,something elses也需要设置。

EstimatedRowHeight

这解决了我的问题。现在SampleTableView.EstimatedRowHeight = SampleTableView.Frame.Height;在加载时仅被调用一次,因为一次只有一个可见的单元格。

文档(苹果,但xamarin也是如此): https://developer.apple.com/documentation/uikit/uitableview/1614925-estimatedrowheight