Bug 10877 - Cannot override static UICollectionViewLayout.layoutAttributesClass
Summary: Cannot override static UICollectionViewLayout.layoutAttributesClass
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 6.3.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2013-03-04 10:06 UTC by Nick
Modified: 2013-03-22 09:07 UTC (History)
4 users (show)

Is this bug a regression?: ---
Last known good build:

test case (517.72 KB, application/zip)
2013-03-20 10:47 UTC, Mike Bluestein

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Nick 2013-03-04 10:06:19 UTC
I have the opposite problem to this http://stackoverflow.com/questions/13487271/monotouch-how-to-override-static-uiview-layerclass, regarding this static method http://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionViewLayout_class/Reference/Reference.html#//apple_ref/occ/clm/UICollectionViewLayout/layoutAttributesClass.

Unlike UIView, where monotouch has omitted the definition of the static method layerClass, presumedly to allow you to define it in a subclass, layoutAttributesClass is defined in UICollectionViewLayout and I have no idea how to override it in my subclass.

I've tried...

    [Export ("layoutAttributesClass")]
    public static Class LayoutAttributesClass {
        get { return new Class(typeof(MyClass)); }

... but this is never called.
Comment 1 Rolf Bjarne Kvinge [MSFT] 2013-03-04 16:49:35 UTC
Can you attach a test case/project?
Comment 2 Nick 2013-03-04 18:34:01 UTC
This might just be a case of documentation as it might never be called for another reason. But the example above gives the following warning:

 Warning CS0108: `MyCustomLayout.LayoutAttributesClass' hides inherited member `MonoTouch.UIKit.UICollectionViewLayout.LayoutAttributesClass'. Use the new keyword if hiding was intended (CS0108) (LayoutAttributesClassTestCase)

What is the recommended way or implementing this... use another name or use the new keyword?
Comment 3 Rolf Bjarne Kvinge [MSFT] 2013-03-07 19:05:04 UTC
Either way should work.
Comment 4 Nick 2013-03-12 12:27:18 UTC
This works fine, was thrown by the warning.
Comment 5 Mike Bluestein 2013-03-20 10:47:15 UTC
Created attachment 3664 [details]
test case

Test case that subclasses UICollectionViewLayoutAttributes with a class called CustomCollectionViewAttributes.

CircleLayout class subclasses UICollectionViewLayout and implements LayoutAttributesClass, but it is never called.

Also, the Copy method on CustomCollectionViewAttributes is not called.

Results in an invalid cast on line 58 in CircleLayout.
Comment 6 Rolf Bjarne Kvinge [MSFT] 2013-03-22 09:07:52 UTC
Here we run into an ugly difference between ObjectiveC and C#.

In ObjectiveC, you're supposed to call CreateForCell on the type you want returned:

[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]


[CustomCollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]

is not the same thing, even if it ends up calling the same method.

Unfortunately this distinction is lost in C#, a static C# method does not know the type that was used to call it. I've added a new CreateForCell overload, where you can do this:

var attributes = UICollectionViewLayoutAttributes.CreateForCell<CustomCollectionViewLayoutAttributes> (path);

and it works fine. A workaround until this has been released, is to add a CreateForCell method on CustomCollectionViewLayoutAttributes:

public static CustomCollectionViewLayoutAttributes CreateForCell (NSIndexPath indexPath)
	global::MonoTouch.UIKit.UIApplication.EnsureUIThread ();
	if (indexPath == null)
		throw new ArgumentNullException ("indexPath");
	var class_ptr = Class.GetHandle (typeof (CustomCollectionViewLayoutAttributes));
	var sel = Selector.GetHandle ("layoutAttributesForCellWithIndexPath:");
	var ptr = MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend_IntPtr (class_ptr, sel, indexPath.Handle);
	return (CustomCollectionViewLayoutAttributes) Runtime.GetNSObject (ptr);

and then call CustomCollectionViewLayoutAttributes.CreateForCell instead of UICollectionViewLayoutAttributes.CreateForCell in CircleLayout.cs

master: 84a0cf5a5da89b771690de5f24821c9b4a9e8a78