Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

CollectionView fails on iOS for version 5.0.0.2401 #15320

Open
timahrentlov opened this issue Apr 19, 2022 · 23 comments
Open

CollectionView fails on iOS for version 5.0.0.2401 #15320

timahrentlov opened this issue Apr 19, 2022 · 23 comments
Labels
s/unverified New report that has yet to be verified t/bug 🐛

Comments

@timahrentlov
Copy link

Description

CollectionView no longer works on iOS 15.4 for version 5.0.0.2401. The items are not displayed and the Application Output has a lot of repeated error messages:

**The behavior of the UICollectionViewFlowLayout is not defined because:
the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.

Please check the values returned by the delegate. The relevant UICollectionViewFlowLayout instance is <Xamarin_Forms_Platform_iOS_ListViewLayout: 0x7faf82745b80>, and it is attached to <UICollectionView: 0x7faf83715c00; frame = (0 0; 350 789); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x600003cac720>; layer = <CALayer: 0x6000035b96e0>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; layout: <Xamarin_Forms_Platform_iOS_ListViewLayout: 0x7faf82745b80>; dataSource: <Xamarin_Forms_Platform_iOS_GroupableItemsViewController_1: 0x7faf82745dc0>>.
2022-04-19 09:01:35.558971+0200 CollectionViewTutorial.iOS[20419:17713466] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.**

Steps to Reproduce

  1. Download CollectionViewTutorial from https://github.com/xamarin/xamarin-forms-samples/tree/main/GetStarted/Tutorials/CollectionViewTutorial
  2. Run it on iOS 15.4 in simulator
  3. Observe that it works
  4. Upgrade XF to 5.0.0.2401
  5. Run it again on iOS 15.4 in simulator
  6. Observe the missing output and the errors in the output

Expected Behavior

I would expected items to be displayed and no UICollectionView errors in the log

Actual Behavior

No items are displayed and there are errors in the log

Basic Information

  • Version with issue: 5.0.0.2401
  • Last known good version: 5.0.0.2337
  • iOS: 15.4

Workaround

Downgrade to XF 5.0.0.2337

@timahrentlov timahrentlov added s/unverified New report that has yet to be verified t/bug 🐛 labels Apr 19, 2022
@ajramos27
Copy link

It seems related to #13323

@softlion
Copy link
Contributor

softlion commented May 3, 2022

There is only one solution to fix this CollectionView hell on iOS. Fix it definetely. 5 years that it's flowed. I proposed to fix it definetely as i already did it in mvvmcross. But get no echo.

@jfversluis
Copy link
Member

Not sure what you mean @softlion but if you have some ideas on how to fix CollectionView issues, I'm very open to your PRs!

@softlion
Copy link
Contributor

softlion commented May 3, 2022

Not sure what you mean @softlion but if you have some ideas on how to fix CollectionView issues, I'm very open to your PRs!

Would that go into maui, or is it the same code for maui ?

@plafuma
Copy link

plafuma commented May 12, 2022

Hello,
We encounter the same problem (iOS only) and it prevent us to upgrade from XF 4.8 to 5.0.0.x. We are also using Mvvmcross.
From what i see, in my case, this problem occurs when collectionViews are embedded in a stacklayout on which we play with the IsVisible property.

@timahrentlov
Copy link
Author

I believe we are at a junction where we (and the major client I'm working for) will have to stop using CollectionView due to it's iOS problems. The workarounds like MeasureFirstItem does not seem to work in all cases. I dare not go back to the ListView, so I'm contemplating using https://github.com/roubachof/Sharpnado.CollectionView or perhaps the control from SyncFusion.

@follesoe
Copy link

follesoe commented Jun 7, 2022

Observe the same issue for CarouselView, which uses CollectionView under the hoods. Reverting from 5.0.0.2401 to 5.0.0.2337 resolved the issue.

@praeclarum
Copy link
Contributor

@jfversluis The problem is your use of FlowLayout to do something it wasn’t designed for.

Don’t size collection view cells based on math while using FlowLayout - it’s too picky and you’ll never get the math right. Or it will just crash on you. You’re constantly competing against whatever layout code Apple wrote.

Instead, write a new Layout that does the math/calls Measure/whatever instead. There are some nice WWDC videos on how to write custom layouts for CollectionView. That way you are guaranteed to get the cell sizes you want, you can put them where you want, and you won’t be fighting Apple’s default layout.

@follesoe
Copy link

follesoe commented Aug 2, 2022

Isse still present in latest Xamarin.Forms 5.0.0.2515, but not in older 5.0.0.2337.

@ToolmakerSteve
Copy link

ToolmakerSteve commented Aug 4, 2022

See the two possible work-arounds in #13323:

  • ItemSizingStrategy="MeasureFirstItem".
  • Display at first with no items. After a slight delay, add the items.

@rs-mobitech
Copy link

rs-mobitech commented Aug 10, 2022

Don't worry guys, just tell your users to wait, recode to use MAUI, wait another year for MS to fix it on MAUI and then when all that doesn't yet work just hand code something yourself. Great example here of why XF (maybe MAUI) won't catch on. Not enough testing by MS, minimal support and issues that last for many years while MS are busy creating the next MAUI is wonderful video.

@timahrentlov
Copy link
Author

Let's hope that MS will attend to it soon. But it has surfaced something about the abstraction principle I previously didn't consider when comparing to drawn controls; That the developers aren't necessarily skilled enough to do a proper encapsulation of the underlying system control. They don't necessarily know the do's and the don'ts of the platform.

@softlion
Copy link
Contributor

Will PR something, definetly, as the current maui version is unusable. I can't release my app update because of it.

@softlion
Copy link
Contributor

note that in XF, the easy fix is to await Task.Delay(1) after EVERY collection viewmodel
update.

@timahrentlov
Copy link
Author

timahrentlov commented Aug 11, 2022

Timing hacks are not easily applicable to reactive architectures, like DynamicData's SourceCache that maintains the items in the collection. Neither should they be.

@rs-mobitech
Copy link

Any update from anyone ?

@RhomGit
Copy link

RhomGit commented Aug 28, 2022

This bug is affecting CarouselView for us.

Downgrading to 2337 from 2515 isn't an option due to other dependencies.
Task.Delay(50) after setting the view model doesn't work either.
There is no ItemSizingStrategy for CarouselView so even if I wanted to (which I don't) I can't set this.

A pretty serious regression no?

Any update from anyone ?

@jwoeste
Copy link

jwoeste commented Aug 29, 2022

If its useful to anyone on this thread (while waiting for an official fix) Ive found this (not so pretty) workaround for my specific case:

I have a CollectionView in a sfPopUp (Syncfusion Popup)). On showing the Popup the collection view is empty (using "color blended layers" in the simulator revealed that there were indeed items in my collection view, they were just not visible). Changing orientation of the device re-rendered the screen and the CollectionView was now visible.

The Workaround:

I created a bindable property to the viewmodel, bool isCollectionViewVisible (default false);
Then on the page I bind the IsVisible property of the collection view to the isCollectionViewVisible property.

Setting the isCollectionViewVisible property to true now re-renders the CollectionView and everything is fine. This can then be done after the popup is opened (or the OnAppearing event, given that the underlying viewmodel is populated and ready to go).

Not proud of the workaround but it works.

It seems there is some kind of issue with the timing of the various events when rendering on iOS.

@flacidsnake
Copy link

I'm having the same issue with version 5.0.0.2515, so far I downgraded to 5.0.0.2478 and it works.

@DenisLaky
Copy link

Any update regarding this issue? It looks strange that no updates, because it's something that breaks CollectionView in my case and no items are visible.

@albyrock87
Copy link

I have a fix until Microsoft decides to fix this in the source code.. I might even propose a PR but I don't have time now.
I hope this helps the community in the mean time.

Write your own iOS collection view renderer which overrides SelectLayout

    [assembly: ExportRenderer(typeof(CollectionView), typeof(MyCollectionViewRenderer))]
    public class MyCollectionViewRenderer : GroupableItemsViewRenderer<GroupableItemsView, GroupableItemsViewController<GroupableItemsView>>
    {
        protected override ItemsViewLayout SelectLayout()
        {
            var itemSizingStrategy = ItemsView.ItemSizingStrategy;
            var itemsLayout = ItemsView.ItemsLayout;

            if (itemsLayout is GridItemsLayout gridItemsLayout)
            {
                // TODO: implement MyGridViewLayout similarly to MyListViewLayout
                return new MyGridViewLayout(gridItemsLayout, itemSizingStrategy);
            }

            if (itemsLayout is LinearItemsLayout listItemsLayout)
            {
                return new MyListViewLayout(listItemsLayout, itemSizingStrategy, ItemsView);
            }

            // Fall back to vertical list
            return new MyListViewLayout(new LinearItemsLayout(ItemsLayoutOrientation.Vertical), itemSizingStrategy, ItemsView);
        }
    }

Write your own list view layout which overrides ConstrainTo

    public class MyListViewLayout : ItemsViewLayout
    {
        private readonly GroupableItemsView _itemsView;

        public MyListViewLayout(LinearItemsLayout itemsLayout, ItemSizingStrategy itemSizingStrategy, GroupableItemsView itemsView)
            : base(itemsLayout, itemSizingStrategy)
        {
            _itemsView = itemsView;
        }

        public override void ConstrainTo(CGSize size)
        {
            // See
            // - https://stackoverflow.com/questions/55667820/frame-size-of-uicollectionview-is-bigger-than-size-of-uiscreen
            // - https://github.com/xamarin/Xamarin.Forms/issues/15320
            var constrainedItemsViewDimension =
                ScrollDirection == UICollectionViewScrollDirection.Vertical 
                    ? _itemsView.Width 
                    : _itemsView.Height;
            
            var constrainedDimension =
                ScrollDirection == UICollectionViewScrollDirection.Vertical 
                    ? size.Width 
                    : size.Height;

            // When ItemsView dimension is available (>0) constrain to it
            if (constrainedItemsViewDimension > 0 && constrainedItemsViewDimension < constrainedDimension)
            {
                constrainedDimension = (float)constrainedItemsViewDimension;
            }

            ConstrainedDimension = (float)Math.Floor(constrainedDimension);
            DetermineCellSize();
        }

@softlion
Copy link
Contributor

softlion commented May 9, 2023

Is there something similar for maui ?

@mrjavicho
Copy link

@albyrock87 thank you for that code snippet, seems to work fine. Could anyone from MS tell me how to create a PR to fix this? I mean, what will be necessary for it to actually get merged

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
s/unverified New report that has yet to be verified t/bug 🐛
Projects
None yet
Development

No branches or pull requests