4

Today I updated to Xamarin.iOS 8.6.0.51 and switched to the new Unified API.

Now I want to get the keyboard size (this code worked before):

var val = new NSValue (notification.UserInfo.ValueForKey (UIKeyboard.FrameBeginUserInfoKey).Handle);
RectangleF keyboardSize = val.RectangleFValue;

With the help of the migration tool the RectangleF is converted to CGRect, but the errors I'm getting here are

Error CS1540: Cannot access protected member Foundation.NSValue.NSValue(System.IntPtr)' via a qualifier of type Foundation.NSValue'. The qualifier must be of type `MyApp.SomeViewController' or derived from it (CS1540)

and

Error CS0122: `Foundation.NSValue.NSValue(System.IntPtr)' is inaccessible due to its protection level (CS0122)

How can I solve this? I can delete new NSValue(...), but RectangleFValue still doesn't work and I would need a replacement/another way.

Edit:

According to jonathanpeppers I modified my code to:

NSValue keyboardFrameBegin = (NSValue)notification.UserInfo.ValueForKey (UIKeyboard.FrameBeginUserInfoKey);
CGRect keyboardSize = keyboardFrameBegin.CGRectValue;

This doesn't throw an error anymore, but I can't test it further because I'm in the process of migrating to the Unified API and there are still some errors to correct.

testing
  • 19,681
  • 50
  • 236
  • 417

2 Answers2

9

Can you just use a cast:

var val = (NSValue)notification.UserInfo.ValueForKey (UIKeyboard.FrameBeginUserInfoKey);
RectangleF keyboardSize = val.RectangleFValue;

Only rarely should you have to mess with handles in Xamarin.iOS.

To be absolutely sure what to cast to, debug and see what the underlying type is first:

NSObject val = notification.UserInfo.ValueForKey (UIKeyboard.FrameBeginUserInfoKey);
Console.WriteLine("Type: " + val.GetType());
jonathanpeppers
  • 26,115
  • 21
  • 99
  • 182
  • I tried your approach (see my edited question) and it doesn't throw an error at this place. I'll give you the tick if I was able to fully test my application. – testing Jan 13 '15 at 13:42
1

The .ctor(IntPtr) constructors in NSObject could be misused and causes issue later. Also, like @jonathanpeppers mentioned, they were not required for many scenarios (like this one).

Another way to do this (e.g. if you have nothing else but an handle), as documented here, is to use the ObjCRuntime.Runtime.GetNSObject<T> (IntPtr) method. That will ensure the NSObject-subclass is created correctly.

poupou
  • 43,413
  • 6
  • 77
  • 174