我知道它什么时候加载...(webViewDidFinishLoad),但我想用
[webView.layer renderInContext:UIGraphicsGetCurrentContext()];
从UIWebView创建图像。偶尔我会在webView完成渲染之前获取图像。我可以使用performSelector来延迟图像的获取,但是等待的数量是任意的和脆弱的。
答案 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
}
这样的事可能有用。