简体   繁体   中英

Xamarin UICollectionView some cells disappear after scrolling down and back

I have a problem with UICollectionView, exactly with cells... When I'm scrolling down and back so some cells are just empty. They just disappear something like this:

在此输入图像描述

My ViewDidLoad() in OrdersView:

public override void ViewDidLoad()
      {
            Title = "My Orders..";

            base.ViewDidLoad();

            ordersCollectionView.Frame = new CGRect(ordersCollectionView.Frame.X, ordersCollectionView.Frame.Y, ordersCollectionView.Frame.Width, ordersCollectionView.Frame.Height);
            ordersCollectionView.ScrollEnabled = true;

            var layout = new UICollectionViewFlowLayout
            {
                ItemSize = new CGSize() { Width = ordersCollectionView.Bounds.Width, Height = 80 },
                MinimumInteritemSpacing = 0,
                MinimumLineSpacing = 2,
                ScrollDirection = UICollectionViewScrollDirection.Vertical
            };

            ordersCollectionView.SetCollectionViewLayout(layout, true);

            this.ClearBindings(_source);
            _source = new OrdersCollectionViewSource(ordersCollectionView);

            this.AddBindings(new Dictionary<object, string>
                {
                    { _source, "ItemsSource Orders; SelectedItem SelectedOrder; SelectionChangedCommand ShowOrderDetailCommand" }
                });

            ordersCollectionView.Source = _source;
            ordersCollectionView.ReloadData();

            Mvx.Resolve<IMvxMessenger>().SubscribeOnMainThread<OrdersLoadedMessage>(mess =>
            {
                this.ClearBindings(_source);

                _source = new OrdersCollectionViewSource(ordersCollectionView);
                this.AddBindings(new Dictionary<object, string>
                        {
                            { _source, "ItemsSource Orders; SelectedItem SelectedOrder; SelectionChangedCommand ShowOrderDetailCommand" }
                        });

                ordersCollectionView.Source = _source;
                ordersCollectionView.ReloadData();

            }, MvxReference.Strong);

            InitializeRefreshControl();

            ViewMessages.ViewCreatedMessages(this, "OrdersView", ViewModel);
        }

OrdersCollectionViewSource:

 public class OrdersCollectionViewSource : MvxCollectionViewSource
    {
        private static readonly NSString CellIdentifier = new NSString("OrdersCollectionViewCell");

        public OrdersCollectionViewSource(UICollectionView collectionView) : base(collectionView)
        {
            collectionView.RegisterClassForCell(typeof(OrdersCollectionViewCell), CellIdentifier);
        }

        protected override UICollectionViewCell GetOrCreateCellFor(UICollectionView collectionView, NSIndexPath indexPath, object item)
        {
            var cell = (UICollectionViewCell)collectionView.DequeueReusableCell(CellIdentifier, indexPath);
            cell.BackgroundColor = UIColor.FromRGB(237, 237, 237);
            return cell;
        }
    }

OrdersCollectionViewCell:

   public class OrdersCollectionViewCell : MvxCollectionViewCell
    {
        [Export("initWithFrame:")]
        public OrdersCollectionViewCell(CGRect frame) : base(frame)
        {
            Layer.BackgroundColor = new CGColor(220, 25, 25, 255);

            //left
            var labelName = new UILabel();
            labelName.Frame = new CGRect(10f, 15f, (float)(Bounds.Width / 2 + 20), 20f); 
            labelName.Font = UIFont.PreferredHeadline;
            labelName.TextColor = UIColor.FromRGBA(90, 24, 24, 255);
            labelName.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin;
            labelName.Text = "Text";

            var labelPickupDate = new UILabel();
            labelPickupDate.Frame = new CGRect(10f, 45f, (float)(Bounds.Width / 2 - 10), 20f);
            labelPickupDate.Font = UIFont.PreferredBody;
            labelPickupDate.TextColor = UIColor.Black;
            labelPickupDate.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin;

            //right
            var labelPrice = new UILabel();
            labelPrice.Frame = new CGRect((float)(Bounds.Width / 2), 45f, (float)(Bounds.Width / 2 - 10), 20f);
            labelPrice.TextAlignment = UITextAlignment.Right;
            labelPrice.Font = UIFont.PreferredBody;
            labelPrice.TextColor = UIColor.Black;
            labelPrice.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin;

            var labelStatus = new UILabel();
            labelStatus.Frame = new CGRect((float)(Bounds.Width / 2), 15f, (float)(Bounds.Width / 2 - 10f), 20f);
            labelStatus.TextAlignment = UITextAlignment.Right;
            labelStatus.Font = UIFont.PreferredHeadline;
            labelStatus.TextColor = UIColor.FromRGBA(15, 113, 10, 255);
            labelStatus.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin;

            Add(labelName);
            Add(labelPickupDate);
            Add(labelStatus);
            Add(labelPrice);

            this.DelayBind(() =>
            {
                var set = this.CreateBindingSet<OrdersCollectionViewCell, Order>();
                set.Bind(labelPickupDate).For(q => q.Text).To(vm => vm.PickupDate).WithConversion("StringDateTimeConverter");
                set.Bind(labelStatus).For(q => q.Text).To(vm => vm.OrderStatus);
                set.Bind(labelPrice).To(vm => vm.Sum).WithConversion("CreditConverter");

                set.Apply();
            });
        }
    }

I found here some similarly problems but everything in xcode.. so I tried something but it still doesn't work well.

EDIT - MY SOLUTION:

protected override UICollectionViewCell GetOrCreateCellFor(UICollectionView collectionView, NSIndexPath indexPath, object item)
{
      var cell = (UICollectionViewCell)collectionView.DequeueReusableCell(CellIdentifier, indexPath);
      cell.BackgroundColor = UIColor.FromRGB(237, 237, 237);

      var order = (Order) item;

      var test = (OrdersCollectionViewCell) cell;
      test.labelName.Text = "Name";
      test.labelPickupDate.Text = StringConvertor.StringDateTime(order.PickupDate);
      test.labelPrice.Text = StringConvertor.PriceConvertor(order.Sum);
      test.labelStatus.Text = order.OrderStatus;

      return test;
}

I had a very similar problem. It is because your table reuses cells. dequeueReusableCellWithIdentifier will reuse the same cell references when scrolling and it may not preserve the text you intended to display.

Your GetOrCreateCellFor function contains a call to DequeueReusableCell . You should also set the cell's text within this function (eg cell.labelName.text = "my text here" ).

protected override UICollectionViewCell GetOrCreateCellFor(UICollectionView collectionView, NSIndexPath indexPath, object item)
{
    var cell = (UICollectionViewCell)collectionView.DequeueReusableCell(CellIdentifier, indexPath);
    cell.BackgroundColor = UIColor.FromRGB(237, 237, 237);
    cell.labelName.text = "Your label here"
    cell.labelPickupDate.text = "Your pickup date here"
    cell.labelPrice.text = "Your price here"
    cell.labelStatus.text = "Your status here"
    return cell;
}

Please see this answer below for the full explanation. Let me know if you have any questions.

https://stackoverflow.com/a/43164656/2179970

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM