How to hide keyboardAccessory bar in Xamarin.iOS

What is the keyboardAccessory bar?
As the image below, when user focus on an input in a webview, the keyboard will be launched with a keyboardAccessory bar. User can click “Done” to hide the keyboard.

Screen Shot 2015-09-25 at 5.01.19 pm

Sometime we don’t want it appears, we can also remove it in our codes.
In iOS, there is a library can do this
https://github.com/ionic-team/ionic-plugin-keyboard/blob/master/src/ios/IonicKeyboard.m

But in Xamarin.iOS, we can just use these codes. It is simple and easily to use.

    public class HideFormAccessoryBar
    {

        [DllImport("/usr/lib/libobjc.dylib")]
        extern static IntPtr class_getInstanceMethod(IntPtr classHandle, IntPtr Selector);

        [DllImport("/usr/lib/libobjc.dylib")]
        extern static IntPtr method_getImplementation(IntPtr method);

        [DllImport("/usr/lib/libobjc.dylib")]
        extern static IntPtr imp_implementationWithBlock(ref BlockLiteral block);

        [DllImport("/usr/lib/libobjc.dylib")]
        extern static void method_setImplementation(IntPtr method, IntPtr imp);

        static IntPtr UIOriginalImp;
        static IntPtr WKOriginalImp;
        static bool _hideFormAccessoryBar;
        public static void SetHideFormAccessoryBar(bool hide)
        {
            if (hide == _hideFormAccessoryBar)
                return;
            var uiMethod = class_getInstanceMethod(Class.GetHandle("UIWebBrowserView"), new Selector("inputAccessoryView").Handle);
            var wkMethod = class_getInstanceMethod(Class.GetHandle("WKContentView"), new Selector("inputAccessoryView").Handle);

            if(hide)
            {
                UIOriginalImp = method_getImplementation(uiMethod);
                WKOriginalImp = method_getImplementation(wkMethod);

                var block_value = new BlockLiteral();
                CaptureDelegate d = MyCapture;
                block_value.SetupBlock(d, null);
                var nilimp = imp_implementationWithBlock(ref block_value);
                method_setImplementation(uiMethod, nilimp);
                method_setImplementation(wkMethod, nilimp);

            }else
            {
                method_setImplementation(uiMethod, UIOriginalImp);
                method_setImplementation(wkMethod, WKOriginalImp);
            }
            _hideFormAccessoryBar = hide;
        }

        delegate IntPtr CaptureDelegate();

        [MonoPInvokeCallback(typeof(CaptureDelegate))]
        static IntPtr MyCapture()
        {
            return IntPtr.Zero;
        }
    }
Advertisements

Using MvvmCross to link Xamarin Native page and Xamarin Forms page

MvvmCross is a powerful framework, which can be used on Xamarin.IOS, Xamarin.Android and WP. We can use it to binding data, navigation, etc. But it cannot help us to share the UI codes. For example, if we want to build login page, we can use MvvmCross to build the data layer. We need to build a login page for Android, and another page for IOS.

Xamarin Forms can share the UI codes, it means we can build only one login page in Xamarin Forms, and use it both in Android and IOS. Generally speaking, if our project pages are all data, images, something with basic logic, we can use Xamarin Forms pages to build the whole solution.  But if this project use like camera, video/audio player, maps, then Xamarin Forms cannot help us to build these pages.

In our last project, the solution used camera, so that for some basic pages it have to use native pages. As MvvmCross cannot navigate between native page and Xamarin Forms page by default.

But we changed it, as MvvmCross has a outstanding architecture, we write a extension to achieve this. Here is demo

https://github.com/jessejiang0214/MvvmCrossNavigationDemo

For this demo, some steps are import.

  1. Included Xamarin.Forms packages into IOS and Android Project
  2. Init Xamarin.Forms, for IOS, it is in Setup.cs. But in Android, it is in SplashScreen page, if your project doesn’t have that page, you should make sure Xamarin.Forms.Init() before show Xamarin Forms page.
  3. Copy MvxTouchViewPresenter MvxPresenterHelpers MvxFormsDroidPagePresenter pages into your project. For Android project, you need create MvxFormsApplicationActivity, because Xamarin Forms need a host activity in Android.

We didn’t do the same thing in Windows Phone, because Xamarin Forms only support Windows Phone Silverlight in currently version (1.4.4). I don’t like Windows Phone Silverlight, so I just wait for Xamarin Forms support Windows RT, and then use it.

Hope you can enjoy our demo, and build amazing apps based on Xamarin Forms and MvvmCross.