简体   繁体   中英

Xamarin iOS 8, UICollectionView - Error in dequeue reusable UICollectionViewCell

I'm having some trouble implementing a UICollectionView in my UIViewController. It gives me an error in GetCell Failed to marshal the Objective-C object 0x137622db0 (type: ParkXApp_iOS_FamilyCollectionCell). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'ParkXApp_iOS.FamilyCollectionCell' does not have a constructor that takes one IntPtr argument). Failed to marshal the Objective-C object 0x137622db0 (type: ParkXApp_iOS_FamilyCollectionCell). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'ParkXApp_iOS.FamilyCollectionCell' does not have a constructor that takes one IntPtr argument). .

I have implemented next to the monotouch sample code: monotouch sample simple UICollectionView

this is my code:

using System;
using UIKit;
using CoreGraphics;
using System.Collections.Generic;
using ObjCRuntime;
using Foundation;

namespace ParkXApp_iOS
{
public class FamilyView : UIViewController
{
    nfloat navBarHeight;
    nfloat viewWidth;
    nfloat viewHeight;


    public FamilyView ()
    {
    }

    public override void ViewWillAppear (bool animated)
    {
        base.ViewWillAppear (animated);

        Draw ();
    }

    public void Draw () {

        // clean the screen before (re)drawing it
        foreach (var subView in this.View.Subviews) {
            subView.RemoveFromSuperview ();
        }
        this.NavigationItem.SetRightBarButtonItem(null, true);


        // set background
        this.View.BackgroundColor = new UIColor((nfloat)0.99, (nfloat)0.99, (nfloat)0.99, 1);


        // get viewWidth and viewHeight for drawing relative to the screen
        navBarHeight = this.NavigationController.NavigationBar.Frame.GetMaxY ();
        viewWidth = UIScreen.MainScreen.Bounds.Width;
        viewHeight = UIScreen.MainScreen.Bounds.Height - navBarHeight;

        UICollectionViewFlowLayout flowLayout = new UICollectionViewFlowLayout ();
        flowLayout.ItemSize = new CGSize (100, 100);
        flowLayout.ScrollDirection = UICollectionViewScrollDirection.Vertical;
        flowLayout.SectionInset = new UIEdgeInsets (20, 20, 20, 20);

        UICollectionView collectionView = new FamilyCollectionView (flowLayout).CollectionView;
        collectionView.Frame = new CGRect (0, navBarHeight, viewWidth, viewHeight);
        collectionView.ContentInset = new UIEdgeInsets (50, 0, 0, 0);

        this.View.AddSubview (collectionView);


    }
}


public class FamilyCollectionView : UICollectionViewController
{

    List<string> familyMembers;

    public FamilyCollectionView (UICollectionViewLayout layout) : base (layout) {

        familyMembers = new List<string> ();

        for (int i = 0; i < 5; i++) {
            familyMembers.Add ("tom");
        }


        CollectionView.RegisterClassForCell (typeof(FamilyCollectionCell), "FamilyCollectionCell");

        UIMenuController.SharedMenuController.MenuItems = new UIMenuItem[] {
            new UIMenuItem ("Custom", new Selector ("custom"))
        };
    }

    public override nint NumberOfSections (UICollectionView collectionView)
    {
        return 1;
    }

    public override nint GetItemsCount (UICollectionView collectionView, nint section)
    {
        return familyMembers.Count;
    }

    public override UICollectionViewCell GetCell (UICollectionView collectionView, Foundation.NSIndexPath indexPath)
    {
        try {
        var cell = (FamilyCollectionCell)collectionView.DequeueReusableCell ("FamilyCollectionCell", indexPath);

        cell.nameLabel.Text = familyMembers [indexPath.Row];

        return cell;
        } catch (Exception ex) {
            Console.WriteLine (ex.Message);
        }
        return null;
    }

    public override void ItemHighlighted (UICollectionView collectionView, NSIndexPath indexPath)
    {
        var cell = collectionView.CellForItem (indexPath);
        cell.ContentView.BackgroundColor = UIColor.Yellow;
    }

    public override void ItemUnhighlighted (UICollectionView collectionView, NSIndexPath indexPath)
    {
        var cell = collectionView.CellForItem (indexPath);
        cell.ContentView.BackgroundColor = UIColor.White;
    }

    public override bool ShouldHighlightItem (UICollectionView collectionView, NSIndexPath indexPath)
    {
        return true;
    }



}

public class FamilyCollectionCell : UICollectionViewCell
{
    public UILabel nameLabel;

    public FamilyCollectionCell (CGRect frame) : base (frame)
    {
        BackgroundColor = UIColor.Orange;

        ContentView.Layer.BorderColor = UIColor.LightGray.CGColor;
        ContentView.Layer.BorderWidth = 2.0f;
        ContentView.BackgroundColor = UIColor.White;
        ContentView.Transform = CGAffineTransform.MakeScale (0.8f, 0.8f);

        nameLabel = new UILabel ();
        nameLabel.Text = "name";
        nameLabel.SizeToFit ();
        nameLabel.Center = ContentView.Center;

        ContentView.AddSubview (nameLabel);


    }

    [Export("custom")]
    void Custom()
    {
        Console.WriteLine ("some code in the cell");
    }

    public override bool CanPerform (Selector action, NSObject withSender)
    {
        if (action == new Selector ("custom"))
            return true;
        else
            return false;
    }
}
}

To test it you should be able to copy-paste the code and run it in a solution. It is completely independent.

Thanks in advance!

You need to add this:

    [Export ("initWithFrame:")]

in you cell like so

public class FamilyCollectionCell : UICollectionViewCell
{
    public UILabel nameLabel;

    [Export ("initWithFrame:")] // ADDED HERE
    public FamilyCollectionCell (CGRect frame) : base (frame)
    {
        BackgroundColor = UIColor.Orange;

        ContentView.Layer.BorderColor = UIColor.LightGray.CGColor;
        ContentView.Layer.BorderWidth = 2.0f;
        ContentView.BackgroundColor = UIColor.White;
        ContentView.Transform = CGAffineTransform.MakeScale (0.8f, 0.8f);

        nameLabel = new UILabel ();
        nameLabel.Text = "name";
        nameLabel.SizeToFit ();
        nameLabel.Center = ContentView.Center;

        ContentView.AddSubview (nameLabel);


    }

    [Export("custom")]
    void Custom()
    {
        Console.WriteLine ("some code in the cell");
    }

    public override bool CanPerform (Selector action, NSObject withSender)
    {
        if (action == new Selector ("custom"))
            return true;
        else
            return false;
    }
}

Also that's an interesting way of adding in the collectionView into a viewcontroller. Is there any need for FamilyView? It might be better to add the navbar to the collectionview controller?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM