Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error CS1540/CS0122: Getting keyboard size doesn't work after switching to Unified API

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.

like image 210
testing Avatar asked Dec 26 '22 00:12

testing


2 Answers

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());
like image 170
jonathanpeppers Avatar answered Jan 01 '23 04:01

jonathanpeppers


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.

like image 36
poupou Avatar answered Jan 01 '23 03:01

poupou