我想允许用户将缩放因子与文档相关联,并在UIWebView中显示该文档时将其用作起点。但是,似乎webViewDidFinishLoad:
仅表示内存中加载的结束,不包括渲染或布局。以下是演示此问题的示例代码:
- (void)viewDidLoad {
[super viewDidLoad];
UIWebView *webView = (UIWebView *)self.view;
webView.delegate = self;
webView.scalesPageToFit = YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSString *urlString = [[NSBundle mainBundle] pathForResource:@"Doc" ofType:@"pdf"];
NSURL *file = [NSURL fileURLWithPath:urlString];
[(UIWebView *)self.view loadRequest:[NSURLRequest requestWithURL:file]];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!webView.isLoading) {
[webView.scrollView setZoomScale:1.5 animated:YES];
}
}
对setZoomScale的调用:执行时没有任何效果(即文件以缩放因子1.0显示),显然是因为它发生在滚动视图处于可以处理它的某个状态之前。如果我将上面的最终方法改为以下内容,那么一切都按照我的希望进行。
- (void)delayedZoomMethod {
[((UIWebView *)self.view).scrollView setZoomScale:1.5 animated:YES];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self performSelector:@selector(delayedZoomMethod) withObject:nil afterDelay:1.0];
}
这当然是一个坏主意,因为1.0延迟是任意的,对于绝大多数情况来说可能太长,并且在某些未知条件下可能会太短。
文档说,“如果想要自定义Web视图的滚动行为,您的应用程序可以访问滚动视图。”是否有人知道Web视图中的通知或属性或它的滚动视图,我可以观察到当该语句变为真时?
答案 0 :(得分:2)
如果您控制了html代码,这可能有所帮助。我已经能够通过以下方式让html事件触发objC方法。
html事件触发将字符串写入window.location的javascript 然后uiwebview使用uiwebviewdelegate接收具有此功能的字符串 web视图:shouldStartLoadWithRequest:navigationType:
这是一种hacky。
但我不认为有办法知道网页视图已经完成渲染,除非您编写了html页面并且可以在页面末尾执行js函数。
答案 1 :(得分:0)
如果您使用UIWebView预览PDF文件,那么它可能不是最佳方式。有一个QLPreViewController(来自iOS 4.0),用于此目的。快速查看预览控制器可以显示以下项目的预览:
答案 2 :(得分:-1)
如果我将上面的最终方法改为以下内容,一切正常 正如我所希望的那样。
这当然是一个坏主意,因为1.0延迟是任意的, 对于绝大多数情况来说可能太长了,很可能会 在一些未知的条件下太短了。
文档说:“您的应用程序可以根据需要访问滚动视图 自定义Web视图的滚动行为。“
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!webView.isLoading) //WEBDIDFINISHLOAD? {
[webView.scrollView setZoomScale:1.5 animated:YES];
}
}
看,didFinishLoadMethod是由NSURLConnection的异步通知调用的, 它不一定在主线程中(因为你的UI更新不起作用)
performSelector..after延迟方法很好。延迟甚至没有任何意义, 您只是跳到主线程来进行UI更新并允许 NSURLConnection通知完成。
如果你说afterDelay:0.0
,这可能不重要这是iOS和OSX中的一种常见情况,您必须弄清楚哪些线程能够更新UI,GCD,NSOperationQueues和后台runLoops在创建的线程上都会使这一点复杂化。
您找到了解决方案,但您需要知道它的含义。在mainThread上调用performSelector,设置一个短延迟并将其固定。