iOS端WebViewRenderer内容不更新问题(Android端正常)
问题原因
iOS端自定义WebView渲染器仅在OnElementChanged方法中加载初始HTML内容,当ViewModel更新绑定的Source属性时,渲染器未监听该属性的变化事件,导致新的HTML内容无法重新加载。
解决方案
修改iOS端的ExtendedWebViewRenderer,添加对Element属性变化的监听,当Source属性更新时重新加载HTML内容:
修改后的iOS渲染器代码
[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))] namespace MyApp.iOS.Renderers { public class ExtendedWebViewRenderer : ViewRenderer<ExtendedWebView, WKWebView> { WKWebView _wkWebView; protected override void OnElementChanged(ElementChangedEventArgs<ExtendedWebView> e) { base.OnElementChanged(e); if (Control == null) { WKWebViewConfiguration config = new WKWebViewConfiguration(); _wkWebView = new WKWebView(Frame, config); _wkWebView.NavigationDelegate = new CustomWKNavigationDelegate(this); SetNativeControl(_wkWebView); } if (e.NewElement != null) { LoadHtmlContent(); } } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); // 监听Source属性变化,重新加载HTML if (e.PropertyName == WebView.SourceProperty.PropertyName) { LoadHtmlContent(); } } private void LoadHtmlContent() { if (Element?.Source is HtmlWebViewSource htmlSource) { _wkWebView.LoadHtmlString(htmlSource.Html, baseUrl: null); _wkWebView.ScrollView.ScrollEnabled = false; _wkWebView.SizeToFit(); } } } public class CustomWKNavigationDelegate : WKNavigationDelegate { ExtendedWebViewRenderer _webViewRenderer; public CustomWKNavigationDelegate(ExtendedWebViewRenderer webViewRenderer) { _webViewRenderer = webViewRenderer; } public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation) { var wv = _webViewRenderer.Element as ExtendedWebView; if (wv != null) { await Task.Delay(100); wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height; } } } }
关键修改点说明
- 新增
OnElementPropertyChanged方法:监听Element的属性变化,当检测到Source属性更新时,调用LoadHtmlContent方法重新加载内容。 - 封装
LoadHtmlContent方法:将原OnElementChanged中的HTML加载逻辑提取为独立方法,避免代码重复,同时保证初始加载和属性更新时的逻辑一致。
额外注意事项
- ViewModel中使用了静态的
HtmlWebViewSource对象,虽然Android端能正常更新,但建议每次更新时创建新的HtmlWebViewSource实例,避免因对象引用未变化导致的绑定更新问题:
private void SetExplanationDetail(string text, string text2) { var newHtmlSource = new HtmlWebViewSource(); newHtmlSource.Html = _style + "<div class=\"text\"><div>" + text + "</div><div>" + text2 + "</div></div>"; _cz = newHtmlSource; NotifyPropertyChanged(nameof(Cz)); }
内容的提问来源于stack exchange,提问作者denisaemailova
相关产品推荐
相关产品推荐

