快速滚动时,CollectionView重叠

时间:2019-11-22 03:10:20

标签: xamarin.ios uicollectionview

我有一个集合视图,一旦您开始滚动足够的次数,这些项目就会相互重叠。集合视图建立在情节提要上,但由于它只是一个简单的标签,因此可以通过编程方式完成集合视图项。我不确定为什么会重叠,我花了相当多的时间才让标签今天不截断文本,所以我需要再看一眼我丢失或做错的事情。

我的UIViewController:

public partial class ViewController : UIViewController
{
    public ViewController(IntPtr handle) : base(handle)
    {
    }

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

        var data = new List<string>
        {
            "Short string", "Long long long string", "another one", "this is just a longer string", "this is just silly at this point too long"
        };

        cvMain.RegisterClassForCell(typeof(TextCollectionViewCell), TextCollectionViewCell.Key);
        cvMain.Source = new CollectionViewDataSource(data);
        cvMain.CollectionViewLayout = new UICollectionViewFlowLayout
        {
            MinimumLineSpacing = 0,
            MinimumInteritemSpacing = 0,
            EstimatedItemSize = new CGSize(150, 45),
            ScrollDirection = UICollectionViewScrollDirection.Horizontal
        };
    }
}

我的ViewSource:

public class CollectionViewDataSource : UICollectionViewSource
{
    private readonly List<string> _tabs;

    public CollectionViewDataSource(List<string> tabs)
    {
        _tabs = tabs;
    }

    public override nint GetItemsCount(UICollectionView collectionView, nint section) => _tabs?.Count ?? 0;

    public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
    {
        var cell = (TextCollectionViewCell)collectionView.DequeueReusableCell(TextCollectionViewCell.Key, indexPath);
        var item = _tabs.ElementAtOrDefault(indexPath.Row);

        cell.Update(item);

        return cell;
    }

    public override nint NumberOfSections(UICollectionView collectionView) => 1;
}

我的CollectionViewCell:

public class TextCollectionViewCell : UICollectionViewCell
{
    public static readonly NSString Key = new NSString("TextCollectionViewCell");

    private UILabel _label;

    public TextCollectionViewCell(IntPtr handle) : base(handle)
    {
        // Note: this .ctor should not contain any initialization logic.
    }

    public void Update(string tabLabel)
    {
        _label = new UILabel(Bounds)
        {
            Lines = 0,
            TextColor = UIColor.White,
            Text = tabLabel
        };

        ContentView.AddSubview(_label);
    }

    public override UICollectionViewLayoutAttributes PreferredLayoutAttributesFittingAttributes(UICollectionViewLayoutAttributes layoutAttributes)
    {
        var newLayoutAttributes = (UICollectionViewLayoutAttributes)layoutAttributes.Copy();

        newLayoutAttributes.Frame = new CGRect(new CGPoint(0, 0), _label.AttributedText.Size);
        _label.Frame = new CGRect(new CGPoint(0, 0), _label.AttributedText.Size);

        return newLayoutAttributes;
    }
}

1 个答案:

答案 0 :(得分:1)

调用cell.Update(item);时总是会添加新标签,因此解决它的快速方法是在添加旧标签之前将其删除:

public void Update(string tabLabel)
{
    if (_label != null)
    {
        _label.RemoveFromSuperview();
    }

    _label = new UILabel(Bounds)
    {
        Lines = 0,
        TextColor = UIColor.White,
        Text = tabLabel
    };

    ContentView.AddSubview(_label);
}

我认为,我将更新标签的文本,而不是每次都创建标签:

public class TextCollectionViewCell : UICollectionViewCell
{
    public static readonly NSString Key = new NSString("TextCollectionViewCell");

    private UILabel _label;

    private string _labelText;
    public string labelText
    {
        get { return _labelText; }
        set
        {
            _labelText = value;

            _label.Text = _labelText;
        }
    }

    public TextCollectionViewCell(IntPtr handle) : base(handle)
    {
        // Note: this .ctor should not contain any initialization logic.

        _label = new UILabel(Bounds)
        {
            Lines = 0,
            TextColor = UIColor.White,
        };

        ContentView.AddSubview(_label);
    }


    public override UICollectionViewLayoutAttributes PreferredLayoutAttributesFittingAttributes(UICollectionViewLayoutAttributes layoutAttributes)
    {
        var newLayoutAttributes = (UICollectionViewLayoutAttributes)layoutAttributes.Copy();

        newLayoutAttributes.Frame = new CGRect(new CGPoint(0, 0), _label.AttributedText.Size);
        _label.Frame = new CGRect(new CGPoint(0, 0), _label.AttributedText.Size);

        return newLayoutAttributes;
    }
}

在GetCell中:

public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
    var cell = (TextCollectionViewCell)collectionView.DequeueReusableCell(TextCollectionViewCell.Key, indexPath);
    var item = _tabs.ElementAtOrDefault(indexPath.Row);

    cell.labelText = item;

    return cell;
}

我认为最好:)。