Using the new UICollectionView's List types and layout styles

WP (Smokeball) 146 Reputation points
2021-05-04T13:39:49.68+00:00

I'm not sure if there have been many people who have utilised the iOS 14 Appearance style for UICollectionView. Namely creating a list style that's appearance is set for the sidebar of a UISplitViewController.

I'm having a bit of a tough time trying to translate the corresponding calls into the Xamarin iOS bindings, but definitely could use a hand, here is what I have so far:

    [MvxFromStoryboard("MainMenuTabletView")]
    [ExtendedMvxSplitViewPresentation(ExtendedMasterDetailPosition.Primary)]
    public partial class MainMenuTabletView : MvxViewController<MainMenuTabletViewModel>
    {
        private UICollectionView _collectionView;

        public MainMenuTabletView(IntPtr handle) : base(handle)
        {
        }

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

            var config = new UICollectionLayoutListConfiguration(UICollectionLayoutListAppearance.Sidebar);

            config.HeaderMode = UICollectionLayoutListHeaderMode.FirstItemInSection;
            config.BackgroundColor = UIColor.Blue;

            _collectionView = UICollectionViewCompositionalLayout.GetLayout(config).CollectionView;
            View.AddSubview(_collectionView);

            _collectionView.TranslatesAutoresizingMaskIntoConstraints = false;
            NSLayoutConstraint.ActivateConstraints(new[]
            {
                _collectionView.TopAnchor.ConstraintEqualTo(View.LayoutMarginsGuide.TopAnchor, 0.0f),
                _collectionView.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor, 0.0f),
                _collectionView.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor, 0.0f),
                _collectionView.BottomAnchor.ConstraintEqualTo(View.BottomAnchor, 0.0f)
            });

            var source = new TestSource(_collectionView);

            _collectionView.Source = source;

            var bindingSet = this.CreateBindingSet<MainMenuTabletView, MainMenuTabletViewModel>();
            bindingSet.Bind(source).To(vm => vm.QuickAddActions);
            bindingSet.Bind(source).For(v => v.SelectionChangedCommand).To(vm => vm.QuickAddActionSelectedCommand);
            bindingSet.Apply();

        }

    }

    public class TestSource : MvxCollectionViewSource
    {
        private UICollectionViewCellRegistration _registration;

        public TestSource(UICollectionView collectionView) : base(collectionView)
        {
            _registration = UICollectionViewCellRegistration.GetRegistration(typeof(UICollectionViewListCell), (cell, index, item) =>
            {
                var content = cell.ContentConfiguration as UIListContentConfiguration;
                var menuItem = ((CustomBoxingNSOject)item).BoxedObj as MainMenuSectionItem;
                content.Text = menuItem.DisplayName;

                cell.ContentConfiguration = content;
            });
        }

        public TestSource(UICollectionView collectionView, NSString defaultCellIdentifier) : base(collectionView, defaultCellIdentifier)
        {
        }

        protected override UICollectionViewCell GetOrCreateCellFor(UICollectionView collectionView, NSIndexPath indexPath, object item)
        {
            var cell = collectionView.DequeueConfiguredReusableCell(_registration, indexPath, new CustomBoxingNSOject(item));

            return cell;
        }
    }

    public class CustomBoxingNSOject : NSObject 
    {
        private object _boxedObj;

        public CustomBoxingNSOject(object obj)
        {
            BoxedObj = obj;
        }

        public object BoxedObj { get => _boxedObj; set => _boxedObj = value; }
    }

So it's currently failing at calling .CollectionView, that is CollectionView is null from the UICollectionViewCompositionalLayout.

So the snippet I saw online in Swift calls it like so:

UICollectionViewCompositionalLayout.list(using: layoutConfig)

But I couldn't find any list method's and the closest that could satisfy it was the GetLayout call.

Furthermore with the UICollectionView.CellRegistration call, the Swift call calls it with generic parameters, i.e. the Cell's type and the Cell's Item Model type, but the Xamarin iOS bindings doesn't have an equivalent.

Developer technologies .NET Xamarin
0 comments No comments
{count} vote

Accepted answer
  1. Cole Xia (Shanghai Wicresoft Co,.Ltd.) 6,756 Reputation points
    2021-05-05T02:54:58.653+00:00

    Hello,

    Welcome to Microsoft Q&A!

    First check the definition of UICollectionViewLayout.CollectionView .

    93737-capture.png

    The property is null until set viewlayout on the Collectionview.

    The correct code

       var layout = UICollectionViewCompositionalLayout.GetLayout(config);  
        UICollectionView collectionView= new UICollectionView(UIScreen.MainScreen.Bounds, layout);  
       View.AddSubview(collectionView);  
    

    Best Regards,
    Cole Xia


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.