question

WPSmokeball-1244 avatar image
0 Votes"
WPSmokeball-1244 asked CurtisConner-4423 commented

Using the new UICollectionView's List types and layout styles

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.

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

ColeXia-MSFT avatar image
0 Votes"
ColeXia-MSFT answered CurtisConner-4423 commented

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.



capture.png (15.6 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

May I know if you have a chance to check my answer ? If you still have problem please let me know.

0 Votes 0 ·

Hi,

I have tried your above code with the new .net 6 core ios and the below code always returns null

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

         var config = new UICollectionLayoutListConfiguration(UICollectionLayoutListAppearance.Sidebar);
         config.HeaderMode = UICollectionLayoutListHeaderMode.None;
         config.HeaderMode = UICollectionLayoutListHeaderMode.FirstItemInSection;


         var layout = UICollectionViewCompositionalLayout.GetLayout(config); // <--- this will always return null, why?
    }

0 Votes 0 ·