如何判断UIWebView何时完成渲染(未加载)?

时间:2011-04-27 19:07:47

标签: objective-c ios uiwebview

我知道它什么时候加载...(webViewDidFinishLoad),但我想用

[webView.layer renderInContext:UIGraphicsGetCurrentContext()];

从UIWebView创建图像。偶尔我会在webView完成渲染之前获取图像。我可以使用performSelector来延迟图像的获取,但是等待的数量是任意的和脆弱的。

6 个答案:

答案 0 :(得分:4)

这可能取决于您需要渲染视图的图形上下文类型,但您可以调用

- (void)drawRect:(CGRect)area forViewPrintFormatter:(UIViewPrintFormatter *)formatter

显然诱使UIWebView认为它正在被打印。如果您的最终目标是捕获整个页面,这可能会有所帮助。我们最近遇到了一个问题,即使页面已经完全加载,调用普通的旧-drawRect:如果其中一些是在屏幕外的话,也不会渲染整个页面。

答案 1 :(得分:2)


使用window.onload或jQuerys $(document).ready事件来触发shouldStartLoad回调怎么样?

类似的东西:

$(document).ready(function(){
    location.href = "app://do.something"
})

并在您的UIWebViewDelegate中执行以下操作:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *url = request.URL;

    if([url.host isEqualToString:@"app"]){
        //maybe check for "do.something"
        //at this point you know, when the DOM is finished
    }
}

使用此方法,您可以将JS代码中的每个可能事件转发到对象代码。

希望有所帮助。代码示例是在浏览器中编写的,因此未经过测试! ; - )

答案 2 :(得分:2)

我在一个完全控制内容的应用程序中遇到了类似的问题。如果您从Web加载任意页面,但如果您知道您的高级DOM结构并且它没有太大改变,则 可以正常工作。

对我有用的是以下内容。

我必须以递归方式找到UIWebView的第UIWebOverflowScrollView个子视图,其中(0, 0, 1024, 768)的框架为layer.sublayers.count。如果我找不到一个,这是一个肯定的迹象,内容尚未呈现。 找到它之后,我会检查此视图的 UIWebOverflowScrollView。渲染完成后,我总会得到一个或三个子图层。但是,如果渲染尚未完成,则内容视图始终具有 最多一个子图层。

现在,特定于我的DOM结构 - 如果您在渲染之前和之后比较子图树,则可能会组成类似的“测试”。对我来说,经验法则是“第一个递归发现的类型为UIWebView的子视图将至少有三个子图层”,对于你来说它可能会有所不同。

无论如何,如果您决定使用这种方法,请务必小心,因为即使您不会因查看bool IsContentScrollView (UIScrollView scrollView) { return scrollView.Frame.Equals (new RectangleF (0, 0, 1024, 768)); } [DllImport ("/usr/lib/libobjc.dylib")] private static extern IntPtr object_getClassName (IntPtr obj); public static string GetClassName (this UIView view) { return Marshal.PtrToStringAuto (object_getClassName (view.Handle)); } bool IsWebOverflowScrollView (UIScrollView scrollView) { return scrollView.GetClassName () == "UIWebOverflowScrollView"; } IEnumerable<UIScrollView> ScrollViewsInside (UIView view) { foreach (var subview in view.Subviews) { foreach (var scrollView in ScrollViewsInside (subview).ToList()) yield return scrollView; if (subview is UIScrollView) yield return (UIScrollView)subview; } } bool CanMakeThumbnail { get { var scrollViews = ScrollViewsInside (this).Where (IsWebOverflowScrollView).ToList (); var contentView = scrollViews.FirstOrDefault (IsContentScrollView); // I don't know why, but this seems to be a good enough heuristic. // When the screen is black, either contentView is null or it has just 1 sublayer. // This may *break* on any iOS updates or DOM changes--be extra careful! if (contentView == null) return false; var contentLayer = contentView.Layer; if (contentLayer == null || contentLayer.Sublayers == null || contentLayer.Sublayers.Length < 3) return false; return true; } } 的视图和层次结构而被拒绝,这种行为也是不可靠的,很可能在未来版本的iOS中进行更改。 iOS 5和iOS 6之间也可能存在不一致的情况。

最后,MonoTouch的代码片段应该直接转换为Objective C:

{{1}}

答案 3 :(得分:0)

defp clock, do: Application.get_env(:my_application, :clock)

def my_function(arg1, arg2) do
  now = clock.now
  # ...
end

答案 4 :(得分:-2)

如果您可以访问HTML文件并且可以对其进行编辑 - 那么只需添加一些特殊变量即可告诉代码完成渲染。
然后使用方法stringByEvaluatingJavaScriptFromString知道你是否应该开始某些行动 下面的例子非常脏,但希望它会有所帮助并给你一个想法:

(void)webViewDidFinishLoad:(UIWebView *)webView
{
    BOOL renderingDone = NO;
    while (!(renderingDone == [[webView stringByEvaluatingJavaScriptFromString:@"yourjavascriptvariable"] isEqualToString:@"YES"]))
    {
        // the app will be "freezed" till the moment when your javascript variable will not get "YES" value 
    }
    // do your stuff, rendering is done 
}

答案 5 :(得分:-4)

if (webView.loading == YES)
        {
            //Load image
        }

这样的事可能有用。