Search code examples
iosxamarin.iostvosuicollectionreusableview

How to properly add a header to my collection view in xamarin.tvos


I've added a header to my collection view but it's not displaying the way I want it to display. I'm trying to have the header show up on the top of my view cells and to the left but instead, I'm stuck with what you see in the attached picture. I'd really appreciate help fixing this. Thanks

/*Header*/


    public class Header:UICollectionReusableView
    {
        public const string identifier = "header";
        public static UILabel text
        {
            get { return text; }

            set
            {
                text.Text = "Header";
                text.TextAlignment = UITextAlignment.Left;
                text.TextColor = UIColor.White;
                text.TranslatesAutoresizingMaskIntoConstraints = false;
            }
        }

        public Header(CGRect frame): base(frame)
        {
            
            AddSubview(text);
            text.TopAnchor.ConstraintLessThanOrEqualTo(SafeAreaLayoutGuide.TopAnchor).Active = true;
            text.HeightAnchor.ConstraintLessThanOrEqualTo(SafeAreaLayoutGuide.HeightAnchor).Active = true;
            text.LeadingAnchor.ConstraintLessThanOrEqualTo(SafeAreaLayoutGuide.LeadingAnchor).Active = true;
            text.TrailingAnchor.ConstraintLessThanOrEqualTo(SafeAreaLayoutGuide.TrailingAnchor).Active = true;
        }

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

        [Export("initWithCoder:")]
        public Header(NSCoder coder) : base(coder) { }

        public override void LayoutSubviews()
        {
            base.LayoutSubviews();
            text.Bounds = Bounds;
        }

    }


/*ViewController*/

public class SectionViewController : UICollectionViewController
    {

        [Export("initWithCollectionViewLayout:")]
        public SectionViewController(UICollectionViewLayout layout) : base(layout)
        {

        }

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

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

            // initialize the method that launches all the collection views registered
            
            CollectionView.RegisterClassForSupplementaryView(typeof(Header), UICollectionElementKindSection.Header, Header.identifier);
            CollectionView.RegisterClassForCell(typeof(UICollectionViewCell), "cells");

        }

        public override void ViewDidLayoutSubviews()
        {
            base.ViewDidLayoutSubviews();
            CollectionView.Frame = new CGRect(0, 0, View.Frame.Width, View.Frame.Height/2);

            //CollectionView.TranslatesAutoresizingMaskIntoConstraints = false;

            CollectionView.BackgroundColor = UIColor.Blue;
        }

        [Export("numberOfSectionsInCollectionView:")]
        public override nint NumberOfSections(UICollectionView collectionView)
        {
            return 1;
        }

        [Export("collectionView:numberOfItemsInSection:")]
        public override nint GetItemsCount(UICollectionView collectionView, nint section)
        {
            return 20;
        }

        [Export("collectionView:cellForItemAtIndexPath:")]
        public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
        {
            var cell = (UICollectionViewCell)collectionView.DequeueReusableCell("cells", indexPath);

            cell.BackgroundColor = UIColor.SystemGreenColor;
            cell.Layer.CornerRadius = 10;

            return cell;
        }

        [Export("collectionView:viewForSupplementaryElementOfKind:atIndexPath:")]
        public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath)
        {
            var header = (Header)collectionView.DequeueReusableSupplementaryView(elementKind, Header.identifier, indexPath);
            header.BackgroundColor = UIColor.SystemRedColor;
            return header;
        }

    }


/*AppleDelegate*/
public class AppDelegate : UIApplicationDelegate
    {
        // class-level declarations

        public override UIWindow Window
        {
            get;
            set;
        }

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            // Override point for customization after application launch.
            // If not required for your application you can safely delete this method

            // create a new window instance based on the screen size
            Window = new UIWindow(UIScreen.MainScreen.Bounds);

            var layout = new UICollectionViewFlowLayout();
            
            var controller = new SectionViewController(layout);
            layout.ScrollDirection = UICollectionViewScrollDirection.Horizontal;
            layout.ItemSize = new CGSize((controller.CollectionView.Frame.Width - 50) / 1.1, (controller.CollectionView.Frame.Width - 10) / 6);
            layout.MinimumLineSpacing = 50.0f;
            layout.MinimumInteritemSpacing = 10.0f;
            layout.SectionInset = new UIEdgeInsets(0, -200, 100, 0);
            layout.SectionHeadersPinToVisibleBounds = true;
            layout.HeaderReferenceSize = new CGSize(controller.CollectionView.Frame.Size.Width / 3, controller.CollectionView.Frame.Size.Height / 9);

            var navController = new UINavigationController(controller);

            Window.RootViewController = navController;

            // make the window visible
            Window.MakeKeyAndVisible();

            return true;
        }

image of the problem, the header is the weird red block


Solution

  • I think the weird red block is probably caused by the wrong layout in header and I did not see you init the text label. Here I wrote a example and it works well:

    public class Header : UICollectionReusableView
    {
        public const string identifier = "header";
        public UILabel text { get; set; }
    
        [Export("initWithFrame:")]
        public Header(CGRect frame) : base(frame)
        {
            text = new UILabel();
            text.Frame = new CGRect(0, 0, 100, 50);
            AddSubview(text);
        }
    
    }
    
    public class SectionViewController : UICollectionViewController
    {
    
        [Export("initWithCollectionViewLayout:")]
        public SectionViewController(UICollectionViewLayout layout) : base(layout)
        {
    
        }
    
        public SectionViewController(IntPtr handle) : base(handle)
        {
        }
    
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
    
            // initialize the method that launches all the collection views registered
    
            CollectionView.RegisterClassForSupplementaryView(typeof(Header), UICollectionElementKindSection.Header, Header.identifier);
            CollectionView.RegisterClassForCell(typeof(UICollectionViewCell), "cells");
    
    
        }
    
        public override void ViewDidLayoutSubviews()
        {
            base.ViewDidLayoutSubviews();
    
            //CollectionView.TranslatesAutoresizingMaskIntoConstraints = false;
    
            UICollectionViewFlowLayout layout = this.Layout as UICollectionViewFlowLayout;
            CollectionView.Frame = new CGRect(0, 0, View.Frame.Width, View.Frame.Height / 2);
    
            layout.ItemSize = new CGSize(100, 100);
            layout.MinimumLineSpacing = 50.0f;
            layout.MinimumInteritemSpacing = 10.0f;
            layout.SectionInset = new UIEdgeInsets(0, -200, 100, 0);
            layout.SectionHeadersPinToVisibleBounds = true;
            layout.HeaderReferenceSize = new CGSize(300, 100);
    
            CollectionView.BackgroundColor = UIColor.Blue;
        }
    
        [Export("numberOfSectionsInCollectionView:")]
        public override nint NumberOfSections(UICollectionView collectionView)
        {
            return 1;
        }
    
        [Export("collectionView:numberOfItemsInSection:")]
        public override nint GetItemsCount(UICollectionView collectionView, nint section)
        {
            return 20;
        }
    
        [Export("collectionView:cellForItemAtIndexPath:")]
        public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
        {
            var cell = (UICollectionViewCell)collectionView.DequeueReusableCell("cells", indexPath);
    
            cell.BackgroundColor = UIColor.SystemGreenColor;
            cell.Layer.CornerRadius = 10;
    
            return cell;
        }
    
        [Export("collectionView:viewForSupplementaryElementOfKind:atIndexPath:")]
        public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath)
        {
            var header = (Header)collectionView.DequeueReusableSupplementaryView(elementKind, Header.identifier, indexPath);
            header.BackgroundColor = UIColor.SystemRedColor;
            header.text.Text = "qweqweq";
            return header;
        }
    }
    

    There are also examples in the document and feel free to ask me any question.