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)
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);
}
}
}