0

I tried to set the Entry auto focus which is inside the WKWebview using xamarin ios renderer

I have created CustomView in xamarin forms and in renderering im adding WKWebView native to that place

Here VWWebview is the Native ios WKwebview and CustomView is a forms view..

Tools => Visual Studio 2019 Build Properties => Link Behaviour - Dont Link (tried Link Framework SDK assemblies only ) too

while in debug, im getting 0x0 for method variable. i can get a reference for wkcontentview and its class handle..

What i missed here?

the auto focus not working in iphone

[References] (Programmatically focus on a form in a webview (WKWebView)

https://social.msdn.microsoft.com/forums/en-US/ec38e195-eb3a-4cbb-87fa-a39a17f63e48/porting-objectivec-code-to-c?forum=xamaringeneral)


public class WKWebViewEx : ViewRenderer<CustomView, VWWebView>
    {
        VWWebView nativeWebView;
        NSMutableUrlRequest MutableReq;
        NSHttpCookie[] nsCookies;
        WKWebViewConfiguration webViewConfig;


        protected override async void OnElementChanged(ElementChangedEventArgs<CustomView> e)
        {
            try
            {

                base.OnElementChanged(e);

                if (e.NewElement != null)
                {
                    if (Control == null)
                    {
                        NSHttpCookieStorage.SharedStorage.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;
                        webViewConfig = new WKWebViewConfiguration();
                        webViewConfig.WebsiteDataStore = WKWebsiteDataStore.NonPersistentDataStore;
                       
                        nativeWebView = new VWWebView(new CGRect(new CGPoint(0, 0), new CGSize(600, 2500)), webViewConfig);
                      
                        SetNativeControl(nativeWebView);
                       
                    }

                    var webview = e.NewElement as VWWKWebview;
                    
                            nativeWebView.LoadRequest(new NSUrlRequest(new NSUrl(GetNSEscapedUrl(Element.Source))));

                }
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        
        public String GetNSEscapedUrl(String sourceStr)
        {
            String source = sourceStr;
            try
            {
              

                String fileName = System.IO.Path.GetFileName(Element.Source);
                var escpStr = Uri.EscapeDataString(fileName);
                source = source.Replace(fileName, escpStr);
            }
            catch (Exception ex)
            {
                Console.WriteLine("UrlException" + ex.Message);
            }
            return source;

        }
       

       
    }



public class VWWebView : WKWebView
    {

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

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

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

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


        public VWWebView(NSCoder coder) : base(coder)
        {
            AllowDisplayingKeyboardWithoutUserAction();
        }

        protected VWWebView(NSObjectFlag t) : base(t)
        {
            AllowDisplayingKeyboardWithoutUserAction();
        }

        protected internal VWWebView(IntPtr handle) : base(handle)
        {
            AllowDisplayingKeyboardWithoutUserAction();
        }

        public VWWebView(CGRect frame, WKWebViewConfiguration configuration) : base(frame, configuration)
        {
            AllowDisplayingKeyboardWithoutUserAction();
        }

        static Selector selector1;
        private static IntPtr _original;
        private void AllowDisplayingKeyboardWithoutUserAction()
        {
            try
            {
                var webView = (WKWebView)this;
                UIView subview = new UIView();
                foreach (UIView view in webView.ScrollView.Subviews)
                {
                    if (view.Class.Name.StartsWith("WK"))
                    {
                        subview = view;
                        break;
                    }
                }
               
               
                IntPtr @class = subview.ClassHandle;//Class.GetHandle("WKContentView");
                NSOperatingSystemVersion iOS_11_3_0 = new NSOperatingSystemVersion(11, 3, 0);

                NSProcessInfo processInfo = NSProcessInfo.ProcessInfo;
                bool isIOS1130 = processInfo.IsOperatingSystemAtLeastVersion(iOS_11_3_0);
                if (isIOS1130)
                {
                    Selector selector = new Selector("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:");
                    IntPtr method = class_getInstanceMethod(@class, selector.Handle);
                    _original = method_getImplementation(method);
                    BlockLiteral block = new BlockLiteral();
                    CaptureDelegate d = MyCapture;
                    block.SetupBlock(d, null);
                    IntPtr @override = imp_implementationWithBlock(ref block);
                    method_setImplementation(method, @override);

                }
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        [MonoNativeFunctionWrapper]
        public delegate void OriginalDelegate(NSObject me, Selector sel, IntPtr arg0, bool arg1, bool arg2, bool arg3, NSObject arg4);

        delegate void CaptureDelegate(NSObject me, IntPtr arg0, bool arg1, bool arg2, bool arg3, NSObject arg4);

        [MonoPInvokeCallback(typeof(CaptureDelegate))]
        static void MyCapture(NSObject me, IntPtr arg0, bool arg1, bool arg2, bool arg3, NSObject arg4)
        {
            try
            {
                OriginalDelegate del = (OriginalDelegate)Marshal.GetDelegateForFunctionPointer(_original, typeof(OriginalDelegate));
                del(me, selector1, arg0, true, arg1, arg3, arg4);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }

0 Answers0