Ios 在webViewDidFinishDownload上调整UIWebView的大小

Ios 在webViewDidFinishDownload上调整UIWebView的大小,ios,objective-c,uiwebview,Ios,Objective C,Uiwebview,假设我有一个UIWebView,它与UIImageView(或其他一些视图)堆叠在一起: 我想调整UIWebView的大小,以便知道UIImageView的放置位置。我的做法是等待UIWebView完成加载: webViewCalculating = YES; while (webViewCalculating == YES) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate di

假设我有一个UIWebView,它与UIImageView(或其他一些视图)堆叠在一起:

我想调整UIWebView的大小,以便知道UIImageView的放置位置。我的做法是等待UIWebView完成加载:

webViewCalculating = YES;
while (webViewCalculating == YES) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
然后,在UIWebView完成加载后,根据以下内容调整其大小:


在这一点之后,我知道我的UIWebView有多高,我可以相应地放置UIImageView。但是,当我按下另一个视图控制器并返回到该视图时,我的hacky
[[nsrunlop currentlunloop]运行模式:NSDefaultRunLoopMode
似乎不会等到我的webView首先完成高度计算。有没有更好的方法让我不等待加载就知道UIWebView的大小?可能类似于NSString的
sizeWithFont
方法?

属性不会重置,因此当您回到此控件时您需要
webviewcomputing=YES;
这样它就不会立即使while循环失败

如果你已经这样做了,你可以试着

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

-(void)webViewDidFinishLoad:(UIWebView *)webView
{

}
委托方法


希望这是有用的。

属性不会重置,因此当您返回此控制器时,需要
webviewcomputing=YES;
这样它就不会立即使while循环失败

如果你已经这样做了,你可以试着

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

-(void)webViewDidFinishLoad:(UIWebView *)webView
{

}
委托方法


希望这是有用的。

您不应该执行while循环来推动运行循环。这是一个非常糟糕的主意。您应该让您的滚动视图容器响应,并在webview完成加载后重新显示子视图。从“大小合理的webview区域”开始。在加载web内容时,可能会以速度显示微调器

我使用的一种技术就是这样做的:

@interface UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight;
@end

@implementation UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight
{
  return [[self stringByEvaluatingJavaScriptFromString:@"document.documentElement.offsetHeight"] floatValue];
}
@end
首先在UIWebView中添加一些分类方法,如下所示:

@interface UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight;
@end

@implementation UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight
{
  return [[self stringByEvaluatingJavaScriptFromString:@"document.documentElement.offsetHeight"] floatValue];
}
@end
然后我编写了一个包含UIWebView的UIView子类。例如:

@interface MyWebView : UIView <UIWebViewDelegate>
@end

@implementation MyWebView 
{
    BOOL _loaded;
    UYIWebView *_webView;
}

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self)
  {
     _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 1)];
     _webView.delegate = self;
     _webView.alpha = 0.0f;
     [self addSubview:_webView]
   }
}

- (CGSize)sizeThatFits:(__unused CGSize)size
{
  if (_loaded)
  {
    CGFloat height = [webView_ documentOffsetHeight];
    CGFloat width = self.frame.size.width;
    return CGSizeMake(width, height);
  }

  return self.frame.size;
}

- (void)sizeToFit
{
  CGSize fittingSize = [self sizeThatFits:CGSizeZero];
  self.bounds = CGRectMake(0, 0, fittingSize.width, fittingSize.height);
}

- (void)layoutSubviews
{
  [super layoutSubviews];
  _webView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
}

- (void)loadHTMLString:(NSString *)htmlString baseURL:(NSURL *)baseURL
{    
  // This code assumes jQuery is already used in the HTML content.  If not, added it as a script resource here too.
  NSString *scriptTag = @"<script type=\"text/javascript\" >jQuery(document).ready(function() { window.location = 'x-webview://ready'; });</script>\n";

  NSString *const headOpeningTag = @"<head>";
  if ([htmlString rangeOfString:headOpeningTag].location != NSNotFound )
  {
    htmlString = [htmlString stringByReplacingOccurrencesOfString:headOpeningTag
                                                       withString:[headOpeningTag stringByAppendingString:headContent]
                                                          options:NSCaseInsensitiveSearch
                                                            range:NSMakeRange(0, [htmlString length])];
  }
  else
  {
    htmlString = [headContent stringByAppendingString:htmlString];
  }

  [_webView loadHTMLString:htmlString baseURL:baseURL];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
  if ([request.URL.scheme isEqualToString:@"x-webview"] && [request.URL.host isEqualToString:@"ready"])
  {
    _loaded = YES;

    [UIView animateWithDuration:0.1
                          delay:0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{ webView.alpha = 1.0f; }
                     completion:nil];

    [self sizeToFit];
    return NO;
  }

  return YES;
}

@end
@interface MyWebView:UIView
@结束
@MyWebView的实现
{
BOOL_加载;
UYIWebView*_webView;
}
-(id)initWithFrame:(CGRect)帧
{
self=[super initWithFrame:frame];
如果(自我)
{
_webView=[[UIWebView alloc]initWithFrame:CGRectMake(0,0,frame.size.width,1)];
_webView.delegate=self;
_webView.alpha=0.0f;
[自添加子视图:_webView]
}
}
-(CGSize)尺寸大小适合:(\u未使用的CGSize)尺寸
{
如果(_已加载)
{
CGFloat高度=[webView_uuDocumentOffsetheight];
CGFloat width=self.frame.size.width;
返回CGSizeMake(宽度、高度);
}
返回self.frame.size;
}
-(空)尺寸合适
{
CGSize fittingSize=[self-sizehattfits:CGSizeZero];
self.bounds=CGRectMake(0,0,fittingSize.width,fittingSize.height);
}
-(无效)布局子视图
{
[超级布局子视图];
_webView.frame=CGRectMake(0,0,self.bounds.size.width,self.bounds.size.height);
}
-(void)loadHTMLString:(NSString*)htmlString baseURL:(NSURL*)baseURL
{    
//这段代码假设jQuery已经在HTML内容中使用。如果没有,也将其作为脚本资源添加到这里。
NSString*scriptTag=@“jQuery(document).ready(function(){window.location='x-webview://ready“;});\n”;
NSString*const headOpeningTag=@;
if([htmlString rangeOfString:headOpeningTag].location!=NSNotFound)
{
htmlString=[htmlString STRING BYREPLACINGOCURNCESOFSTRING:headOpeningTag
withString:[headOpeningTag stringByAppendingString:headContent]
选项:NSCaseInsensitiveSearch
范围:NSMakeRange(0,[htmlString长度]);
}
其他的
{
htmlString=[headContent stringByAppendingString:htmlString];
}
[_webviewloadhtmlstring:htmlString baseURL:baseURL];
}
-(BOOL)webView:(UIWebView*)webView应加载WithRequest:(NSURLRequest*)请求导航类型:(UIWebViewNavigationType)导航类型
{
if([request.URL.scheme IsequalString:@“x-webview”]&&[request.URL.host IsequalString:@“ready”])
{
_加载=是;
[UIView animateWithDuration:0.1
延迟:0
选项:UIViewAnimationOptionAllowUserInteraction
动画:^{webView.alpha=1.0f;}
完成:无];
[自我尺寸匹配];
返回否;
}
返回YES;
}
@结束
因此,基本上这个UIView子类所做的是嵌入一个不可见的webview。然后,当文档加载并呈现时,基于jQuery的JavaScript尝试使用自定义URL方案从当前页面导航。此导航被拒绝。但作为响应,视图大小适合并从HTML文档获取适当的大小新界

注意,您不必使用jQuery。您可以添加一个DOM JavaScript事件。我只是更熟悉jQuery如何处理原始DOM事件


在您的情况下,您必须与scrollview进行通信,告知内容已完成加载,并且scroll view视图应重新布局。您可以使用委托协议或类似协议来完成此操作。或者scrollview可能是“MyWebView”容器UIView子类。根据需要进行调整。

您不应该执行while循环来泵送运行循环。这是一个非常糟糕的主意。您应该让您的滚动视图容器响应,并在webview完成加载后重新显示子视图。从“大小合理的webview区域”开始。在加载web内容时,可能会以速度显示微调器

我使用的一种技术就是这样做的:

@interface UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight;
@end

@implementation UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight
{
  return [[self stringByEvaluatingJavaScriptFromString:@"document.documentElement.offsetHeight"] floatValue];
}
@end
首先在UIWebView中添加一些分类方法,如下所示:

@interface UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight;
@end

@implementation UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight
{
  return [[self stringByEvaluatingJavaScriptFromString:@"document.documentElement.offsetHeight"] floatValue];
}
@end
然后我编写了一个包含UIWebView的UIView子类。例如:

@interface MyWebView : UIView <UIWebViewDelegate>
@end

@implementation MyWebView 
{
    BOOL _loaded;
    UYIWebView *_webView;
}

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self)
  {
     _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 1)];
     _webView.delegate = self;
     _webView.alpha = 0.0f;
     [self addSubview:_webView]
   }
}

- (CGSize)sizeThatFits:(__unused CGSize)size
{
  if (_loaded)
  {
    CGFloat height = [webView_ documentOffsetHeight];
    CGFloat width = self.frame.size.width;
    return CGSizeMake(width, height);
  }

  return self.frame.size;
}

- (void)sizeToFit
{
  CGSize fittingSize = [self sizeThatFits:CGSizeZero];
  self.bounds = CGRectMake(0, 0, fittingSize.width, fittingSize.height);
}

- (void)layoutSubviews
{
  [super layoutSubviews];
  _webView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
}

- (void)loadHTMLString:(NSString *)htmlString baseURL:(NSURL *)baseURL
{    
  // This code assumes jQuery is already used in the HTML content.  If not, added it as a script resource here too.
  NSString *scriptTag = @"<script type=\"text/javascript\" >jQuery(document).ready(function() { window.location = 'x-webview://ready'; });</script>\n";

  NSString *const headOpeningTag = @"<head>";
  if ([htmlString rangeOfString:headOpeningTag].location != NSNotFound )
  {
    htmlString = [htmlString stringByReplacingOccurrencesOfString:headOpeningTag
                                                       withString:[headOpeningTag stringByAppendingString:headContent]
                                                          options:NSCaseInsensitiveSearch
                                                            range:NSMakeRange(0, [htmlString length])];
  }
  else
  {
    htmlString = [headContent stringByAppendingString:htmlString];
  }

  [_webView loadHTMLString:htmlString baseURL:baseURL];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
  if ([request.URL.scheme isEqualToString:@"x-webview"] && [request.URL.host isEqualToString:@"ready"])
  {
    _loaded = YES;

    [UIView animateWithDuration:0.1
                          delay:0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{ webView.alpha = 1.0f; }
                     completion:nil];

    [self sizeToFit];
    return NO;
  }

  return YES;
}

@end
@interface MyWebView:UIView
@结束
@MyWebView的实现
{
BOOL_加载;
UYIWebView*_webView;
}
-(id)initWithFrame:(CGRect)帧
{
self=[super in