2013-05-02 196 views
0

假設我有一個的堆積對一個UIImageView一個UIWebView(或其他視圖):調整大小的UIWebView上webViewDidFinishDownload困境

enter image description here

我想調整我的UIWebView,讓我知道放在哪裏的UIImageView 。我這樣做的方式是等待的UIWebView完成加載:

webViewCalculating = YES; 
while (webViewCalculating == YES) { 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
} 

然後我調整它當一個UIWebView加載完成後,根據this suggestion

-(void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    CGRect frame = webView.frame; 
    frame.size.height = 1; 
    webView.frame = frame; 

    CGSize fittingSize = [webView sizeThatFits:CGSizeZero]; 
    frame.size = fittingSize; 
    webView.frame = frame; 

    heightSoFar += webView.frame.size.height; 
    webViewCalculating = NO; 
} 

這一點後,我d知道我的UIWebView有多高,並且我可以相應地放置我的UIImageView。然而,當我推動另一個視圖控制器,並回到這個,我的哈克[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode似乎並沒有等到我的webView完成計算高度第一。有沒有更好的方式讓我知道我的UIWebView的大小,而無需等待它加載?也許類似於NSString的sizeWithFont方法?

+0

爲什麼你使用while循環呢?一旦webview完成加載,你可以在那裏調整大小嗎? – 2013-05-02 14:17:49

+0

我需要等待看它有多大,否則圖像視圖將重疊。 – 2013-05-03 00:55:29

+0

我不知道我得到這個。難道你只是保持圖像隱藏,直到'didFinishLoad'委託方法被調用,然後計算它的框架並淡入它? – Rog 2013-05-03 02:34:18

回答

4

你不應該在做你的while循環,這是抽運行循環。這是一個非常糟糕的主意。你應該讓你的滾動視圖容器響應,並在webview完成加載時重新佈局子視圖。從「合理大小的網頁瀏覽區域」開始。也許在網頁內容加載時顯示一個微調。

的技術,我以前做的正是這種如下:

首先一些類方法添加到一個UIWebView如下:

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

@implementation UIWebView (ContentSize) 
- (CGFloat)documentOffsetHeight 
{ 
    return [[self stringByEvaluatingJavaScriptFromString:@"document.documentElement.offsetHeight"] floatValue]; 
} 
@end 

然後我寫了一個包含一個UIView子類UIWebView的。例如:

@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 

所以基本上這個UIView子類所做的就是嵌入一個不可見的_webview。然後,當文檔加載並呈現基於jQuery的JavaScript嘗試使用自定義URL方案從當前頁面導航離開時。此導航被困於拒絕。但是,爲了適應這些視圖大小並從HTML文檔中獲取適當的大小。

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

在你的情況下,你將不得不與溝通的scrollview內容已完成加載和滾動視圖視圖應重新佈局。你可以使用委託協議或類似的方法來做到這一點。或者也許scrollview是「MyWebView」容器UIView子類。根據需要調整。

+0

非常感謝,我最後只是使用你的javascript方法,並在最後一次webViewDidFinishLoad調用之後中繼所有子視圖。在UIWebView中沒有像sizeWithFont方法那樣的魔術,事實證明。 – 2013-05-04 01:24:55

-1

屬性沒有重置,所以當你回到這個控制器時,你需要webViewCalculating = YES; ,這樣它就不會立即失敗while循環。

如果你已經這樣做,你可以嘗試把

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

與在

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

} 

委託方法

希望這是非常有用的。

+0

我確實重置了webViewCalculating屬性。把NSRunLoop放到那個委託方法中是無限循環的。 – 2013-05-03 01:10:19