1

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:

enter image description here

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;
}
pnk
  • 293
  • 2
  • 14
  • were you able to solve your issue? – Zion Apr 07 '17 at 11:29
  • I will try solve this problem in monday... but honestly I'm little confused with this solution in Swift code... – pnk Apr 08 '17 at 20:58
  • Please try my suggestion to set cell.label.text = "your text" as stated in my answer. I know the code is in swift, but you don't need the code in this case. the linked answer's explanation shows why the cell contents disappear. – Zion Apr 08 '17 at 23:32
  • hmm still I dont know how to use ur solution in swift code to my implementation in c#... but maybe I have another solution... I did collectionView.ScrollEnabled = false; and set collectionView Height as items count * cell height and I gave collectionView into ScrollView... and it working now..... what you think about this solution? – pnk Apr 10 '17 at 10:43
  • So the number of cells fits within the scroll view without the need to scroll, is that correct? That will fix your error. But what if you require more cells and you need to scroll? If you do, you'll still need to fix the error that you mentioned in your original question. Currently you have your text set in your constructor for: OrdersCollectionViewCell. My suggested solution is just to set your text variables again in the GetOrCreateCellFor function. – Zion Apr 10 '17 at 10:47
  • No numbers dont fits with scroll view... I have 36 items in collectionView and on screen fits only 6.. I can scrolling normal w/o problem. – pnk Apr 10 '17 at 10:51
  • I think cells are loaded all in scrollview and They are not reused loaded... – pnk Apr 10 '17 at 10:54
  • So when Im scrolling now it using only ScrollView and no GetOrCreateCellFor method for reuse antoher cells... – pnk Apr 10 '17 at 10:55
  • I don't understand the "numbers don't fit" part. But if you can scroll without a problem and everything is fixed then I'll let you answer your question :) – Zion Apr 10 '17 at 10:55
  • I thought I have more cells than I can fits within the scrollview without the need to scrolling... – pnk Apr 10 '17 at 10:58
  • I edited my post and added there my solution..... – pnk Apr 10 '17 at 11:03
  • For future reference, you should only post the minimum amount of code possible to show the error that you're getting. – Zion Apr 10 '17 at 11:05
  • hmmm so after testing I found few problem in some situations with my implementation... so I will try your use solution.. Can you help me with your implementation? – pnk Apr 10 '17 at 12:11
  • Yeah, I can help. Where do you set the PickupDate to "10:15 - 5.4.2017"? – Zion Apr 10 '17 at 12:13
  • I bind PickUpDate in OrdersCollectionViewCell, you can see it in my post in DelayBind. – pnk Apr 10 '17 at 12:15
  • Ok, Is it possible to set your label's texts in the GetOrCreateSellFor function? Can you bind the text in the GetOrCreateSellFor function? See my updated answer – Zion Apr 10 '17 at 12:18
  • I cant use Bind here but theoretically I can use values from object item it contains these values but problem is I cant set here labels.. when I use here cell. it doesnt have here labels which are in OrdersCollectionViewCell.... – pnk Apr 10 '17 at 12:21
  • Can you cast the cell within GetOrCreateCellFor function to an OrdersCollectionViewCell? Something like this: `cell = (OrdersCollectionViewCell)cell` – Zion Apr 10 '17 at 12:29
  • ye I tried this... I edited my post with new solution... it seems it working well now – pnk Apr 10 '17 at 12:49
  • Ok awesome! so can you accept my answer? – Zion Apr 10 '17 at 12:50
  • ye man... I will test it but rly seems it working.. so big thanks for help =) – pnk Apr 10 '17 at 12:52
  • Sweet! Glad to help! :) – Zion Apr 10 '17 at 12:53

1 Answers1

0

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 (e.g. 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

Community
  • 1
  • 1
Zion
  • 1,562
  • 13
  • 32