Ios 如何检测UIWebView视图布局的完成

Ios 如何检测UIWebView视图布局的完成,ios,pdf,uiwebview,Ios,Pdf,Uiwebview,我希望允许用户将缩放因子与文档关联,并将其用作在UIWebView中显示该文档的起点。然而,webViewDidFinishLoad:似乎只表示内存加载的结束,不包括渲染或布局。下面是演示该问题的示例代码: - (void)viewDidLoad { [super viewDidLoad]; UIWebView *webView = (UIWebView *)self.view; webView.delegate = self; webView.scalesPag

我希望允许用户将缩放因子与文档关联,并将其用作在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视图或其滚动视图中的通知或属性吗,当该语句变为真时,我可以观察到被告知

如果您可以控制html代码,这可能会有所帮助。我已经能够让html事件以以下方式触发objC方法

html事件触发将字符串写入window.location的javascript 然后,uiwebview使用uiwebviewdelegate通过此函数接收字符串 webView:shouldStartLoadWithRequest:navigationType:

有点黑


但是我认为没有办法知道web视图已经完成渲染,除非您编写了html页面,并且可以在页面末尾插入js函数来执行。

如果您可以控制html代码,这可能会有所帮助。我已经能够让html事件以以下方式触发objC方法

html事件触发将字符串写入window.location的javascript 然后,uiwebview使用uiwebviewdelegate通过此函数接收字符串 webView:shouldStartLoadWithRequest:navigationType:

有点黑


但是我认为没有办法知道web视图已经完成渲染,除非您编写了html页面,并且可以在页面末尾插入js函数来执行。如果您使用UIWebView预览PDF文件,那么这可能不是最好的方法。有一个QLEVIEWCONTROLLER(来自iOS 4.0)用于此目的。快速查看预览控制器可以显示以下项目的预览:

  • 我的工作文件
  • Microsoft Office文档(Office'97及更新版本)
  • 富文本格式(RTF)文档
  • PDF文件
  • 图像
  • 其统一类型标识符(UTI)符合 public.text类型(参见统一类型标识符参考)
  • 逗号分隔值(csv)文件

如果您使用UIWebView预览PDF文件,那么这可能不是最好的方法。有一个QLEVIEWCONTROLLER(来自iOS 4.0)用于此目的。快速查看预览控制器可以显示以下项目的预览:

  • 我的工作文件
  • Microsoft Office文档(Office'97及更新版本)
  • 富文本格式(RTF)文档
  • PDF文件
  • 图像
  • 其统一类型标识符(UTI)符合 public.text类型(参见统一类型标识符参考)
  • 逗号分隔值(csv)文件
如果我将上面的最后一个方法更改为下面的方法,那么一切都会正常工作 正如我所希望的那样

- (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视图的滚动行为。“

看,来自NSURLConnection的异步通知调用了didFinishLoadMethod, 它不一定在主线程中(因为UI更新不起作用)

performSelector..after delay方法可以使用。延迟甚至没有任何意义, 您只是跳转到主线程进行UI更新,并允许 要完成的NSURLConnection通知

如果你在延迟后说:0.0,可能没关系

这是iOS和OSX中的常见情况,您必须弄清楚哪些线程能够更新已创建线程上的UI、GCD、NSOperationQueues和后台运行循环,所有这些都会使这变得复杂

您找到了解决方案,但您需要知道它的含义。在主线程上调用performSelector,设置一个短延迟及其固定值

如果我将上面的最后一个方法更改为下面的方法,那么一切都会正常工作 正如我所希望的那样

- (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视图的滚动行为。“

看,来自NSURLConnection的异步通知调用了didFinishLoadMethod, 它不一定在主线程中(因为UI更新不起作用)

performSelector..after delay方法可以使用。延迟甚至没有任何意义, 您只是跳转到主线程进行UI更新,并允许 要完成的NSURLConnection通知

如果你在延迟后说:0.0,可能没关系

这是iOS和OSX中的常见情况,您必须弄清楚哪些线程能够更新已创建线程上的UI、GCD、NSOperationQueues和后台运行循环,所有这些都会使这变得复杂

您找到了解决方案,但您需要知道它的含义。在主线程上调用performSelector,设置一个短延迟及其固定值。

谢谢,b