Reputation: 387
I am using MonoTouch and have created a class MyButton that extends UIButton. This is actually a simplified example of the same problem I was having with a custom UIScrollView. MyButton extends UIButton and adds some methods to do something simple like increment and decrement a counter (this is just a test case). I also include '[Register("MyButton")]' before my class definition so that it registers with Interface Builder (IB) so that I can add a UIButton and specify its class as MyButton.
What works: I can add an instance of MyButton programmatically to my main view and it displays properly and functions as expected.
What doesn't work: If I try to add a UIButton from IB and specify its class as MyButton, then add an outlet and also specify it is a MyButton type then my app crashes while trying to load the main view with the exception: Unhandled managed exception: Selector invoked from objective-c on a managed object of type iOSCustomUIView.MyButton (0xC2F40D0) that has been GC'ed (System.Exception).
I have found similar questions that have this problem but with view controllers, not views. So I understand that the error is similar, but in the case of a view controller references are lost when pushing new controllers onto the stack, etc. In my case, I don't know why my object has been GC'd before anything has loaded.
I have tried creating additional private member variables to reference my MyButton outlet (btnIncrement), but this did not help. I set breakpoints and the crash occurs when trying to instantiate a new instance of my view controller: (from AppDelegate.cs)
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
viewController = new iOSCustomUIViewViewController ();
window.RootViewController = viewController;
window.MakeKeyAndVisible ();
return true;
}
Is there anything I am missing in order to define a custom UIButton class and use it in IB? Is this a bug in MonoTouch?
Upvotes: 2
Views: 214
Reputation: 387
I got a great response from adamkemp on the Xamarin forum. The solution is that I need to write a constructor that accepts an IntPtr p
argument since that is the constructor called when view objects are created from xib files. In my case, I simply define the following constructor:
public MyButton(IntPtr p) : base(p)
{
// Do initialization stuff here
}
Since I did not have this constructor defined, my object was likely never created. The log message saying that my object has been GC'd was a little misleading in this case. Now, my app views all load successfully.
Upvotes: 2