prosource

UI 웹 보기의 콘텐츠 크기를 결정하는 방법은 무엇입니까?

probook 2023. 6. 7. 22:59
반응형

UI 웹 보기의 콘텐츠 크기를 결정하는 방법은 무엇입니까?

나는 있습니다UIWebView내용이 다른(단일 페이지)저는 그것을 알고 싶습니다.CGSize부모 보기의 크기를 적절하게 조정할 수 있습니다.한 연한것당것.-sizeThatFits:유감스럽게도 웹 뷰의 현재 프레임 크기만 반환합니다.

제 첫 번째 추측은 다음과 같습니다.-sizeThatFits:완전히 틀린 것은 아닙니다.것처럼 , 전송하기 을 최소 합니다.-sizeThatFits:그 후 우리는 피팅 크기로 잘못된 프레임 크기를 수정할 수 있습니다.이것은 끔찍하게 들리지만 사실 그렇게 나쁘지는 않습니다.두 프레임을 서로 바로 변경하기 때문에 보기가 업데이트되지 않고 깜박이지 않습니다.

물론 내용이 로드될 때까지 기다려야 하기 때문에 코드를 입력합니다.-webViewDidFinishLoad:위임 방식

오브제이-C

- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
    CGRect frame = aWebView.frame;
    frame.size.height = 1;
    aWebView.frame = frame;
    CGSize fittingSize = [aWebView sizeThatFits:CGSizeZero];
    frame.size = fittingSize;
    aWebView.frame = frame;

    NSLog(@"size: %f, %f", fittingSize.width, fittingSize.height);
}

스위프트 4.x

func webViewDidFinishLoad(_ webView: UIWebView) {
    var frame = webView.frame
    frame.size.height = 1
    webView.frame = frame
    let fittingSize = webView.sizeThatFits(CGSize.init(width: 0, height: 0))
    frame.size = fittingSize
    webView.frame = frame
}

JavaScript를 사용하는 또 다른 접근 방식(감사합니다. @GregInYEG)이 있습니다.어떤 솔루션이 더 나은 성능을 발휘하는지 확신할 수 없습니다.

두 개의 구식 해결책 중에서 저는 이것이 더 좋습니다.

잘 작동하는 다른 솔루션이 있습니다.

& 6 5, 수 없는 이 방법을 사용하는 입니다. 오트윈의 어프로치에서는 마음에 들지 않고 이해할 수 없는 부분이 있는데, 바로 방법의 사용입니다.[webView sizeThatFits:CGSizeZero] 변수 매개 변를사여하용수▁the▁parameter여로CGSizeZero 변수에 과 같이됩니다.

이 메서드의 기본 구현에서는 뷰 경계 사각형의 크기 부분을 반환합니다.하위 클래스는 이 메서드를 재정의하여 원하는 하위 뷰 레이아웃을 기반으로 사용자 지정 값을 반환할 수 있습니다.예를 들어 UISwitch 개체는 스위치 보기의 표준 크기를 나타내는 고정 크기 값을 반환하고 UIImageView 개체는 현재 표시 중인 이미지의 크기를 반환합니다.

없이 것과 문서를 때 가 제말은그아논없그발것해것같견과다입니다는한결을책의이리무가런▁passed▁what▁to▁reading▁parameter것다니입▁the▁without,▁the▁cameation▁because,같▁document▁any▁solution▁he로 전달되었기 때문입니다. 왜냐하면 문서를 읽었을 때 매개 변수가 전달되었기 때문입니다.[webView sizeThatFits: ...] 적도원하것을가합니다져야가 있어야 .width솔루션을 하여, 는 그솔루사면하용을션원, 폭다같설정다니됩이과음이는의하▁the▁is▁to다▁with▁set로 설정됩니다.webView전하기전틀화를 전의 sizeThatFitsCGSizeZero매개변수 저는 이 이 "iOS 합니다.그래서 저는 이 솔루션이 "우연히" iOS 6에서 작동한다고 주장합니다.

iOS 5.0 이상에서 작동하는 장점이 있는 좀 더 합리적인 접근 방식을 상상했습니다.또한 둘 property 또둘이속의 webView(with the 한상포webView))가 있는 입니다.webView.scrollView.scrollEnabled = NO에 내장되어 있습니다.scrollView.

다음은 레이아웃을 강제로 지정하는 코드입니다.webView.width그리고 그에 상응하는 것을 얻습니다.height을 원래대로 되돌리는.webView자체:

오브제이-C

- (void)webViewDidFinishLoad:(UIWebView *)aWebView
{   
    aWebView.scrollView.scrollEnabled = NO;    // Property available in iOS 5.0 and later 
    CGRect frame = aWebView.frame;

    frame.size.width = 200;       // Your desired width here.
    frame.size.height = 1;        // Set the height to a small one.

    aWebView.frame = frame;       // Set webView's Frame, forcing the Layout of its embedded scrollView with current Frame's constraints (Width set above).

    frame.size.height = aWebView.scrollView.contentSize.height;  // Get the corresponding height from the webView's embedded scrollView.

    aWebView.frame = frame;       // Set the scrollView contentHeight back to the frame itself.
}

스위프트 4.x

func webViewDidFinishLoad(_ aWebView: UIWebView) {

    aWebView.scrollView.isScrollEnabled = false
    var frame = aWebView.frame

    frame.size.width = 200
    frame.size.height = 1

    aWebView.frame = frame
    frame.size.height = aWebView.scrollView.contentSize.height

    aWebView.frame = frame;
}

로 제에서는 참로제예는서에고,는서,webView 지정 사자정포니에 되었습니다.scrollView 것을 것webViews 모든 것들.webViews그들의 들의를 가지고 .webView.scrollView.scrollEnabled = NO그리고 내가 추가해야 했던 마지막 코드 조각은 계산이었습니다.height의 시대의contentSize의 의나습로대관로.scrollView이것들을 내장하기webViews하지만 그것은 나의 것을 요약하는 것만큼 쉬웠습니다.webViewframe.size.height위에서 설명한 속임수로 계산한...

이 질문을 부활시키는 것은 오트윈이 대부분의 시간 동안 일만 한다는 답을 찾았기 때문입니다.

webViewDidFinishLoad메소드는 두 번 이상 호출될 수 있으며 첫 번째 값은 다음에 의해 반환됩니다.sizeThatFits최종 크기의 일부에 불과합니다.그렇다면 어떤 이유로든 다음 전화는sizeThatFits 때에webViewDidFinishLoad화재가 다시 발생하면 이전과 동일한 값이 잘못 반환됩니다!이것은 마치 동시성 문제인 것처럼 동일한 내용에 대해 무작위로 발생합니다.아마도 이 행동은 시간이 지남에 따라 바뀌었을 것입니다. 왜냐하면 저는 iOS 5를 위해 구축하고 있고 또한 그것을 발견했기 때문입니다.sizeToFit거의 동일한 방식으로 작동합니다(이전에는 그렇지 않았습니다).

저는 다음과 같은 간단한 해결책을 결정했습니다.

- (void)webViewDidFinishLoad:(UIWebView *)aWebView
{        
    CGFloat height = [[aWebView stringByEvaluatingJavaScriptFromString:@"document.height"] floatValue];
    CGFloat width = [[aWebView stringByEvaluatingJavaScriptFromString:@"document.width"] floatValue];
    CGRect frame = aWebView.frame;
    frame.size.height = height;
    frame.size.width = width;
    aWebView.frame = frame;
}

Swift(2.2):

func webViewDidFinishLoad(webView: UIWebView) {

    if let heightString = webView.stringByEvaluatingJavaScriptFromString("document.height"),
        widthString = webView.stringByEvaluatingJavaScriptFromString("document.width"),
        height = Float(heightString),
        width = Float(widthString) {

        var rect = webView.frame
        rect.size.height = CGFloat(height)
        rect.size.width = CGFloat(width)
        webView.frame = rect
    }
}

업데이트: 댓글에 언급된 것처럼 콘텐츠가 축소된 경우를 포착하지 못하는 것으로 보입니다.모든 컨텐츠와 OS 버전에 대해 사실인지 확실하지 않습니다. 한 번 시도해 보십시오.

Xcode 8 및 iOS 10에서 웹 보기의 높이를 결정합니다.키는 다음을 사용하여 얻을 수 있습니다.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
    NSLog(@"Webview height is:: %f", height);
}

OR for Swift

 func webViewDidFinishLoad(aWebView:UIWebView){
        let height: Float = (aWebView.stringByEvaluatingJavaScriptFromString("document.body.scrollHeight")?.toFloat())!
        print("Webview height is::\(height)")
    }

간단한 해결책은 그냥 사용하는 것입니다.webView.scrollView.contentSize자바스크립트로 작동하는지는 모르겠습니다.사용된 JavaScript가 없는 경우 다음 작업을 수행합니다.

- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
    CGSize contentSize = aWebView.scrollView.contentSize;
    NSLog(@"webView contentSize: %@", NSStringFromCGSize(contentSize));
}

은 AFAIK를 사용할 수 .[webView sizeThatFits:CGSizeZero]내용 크기를 파악하기 위해서입니다.

경우, 저는 iOS10의 .document.height그렇게document.body.scrollHeight웹 보기에서 문서 높이를 가져오는 솔루션입니다.이 문제는 다음에 대해서도 해결할 수 있습니다.width.

사용 중입니다.UIWebView계층의 ).UITableViewCells연결이 끊어진 것을 발견했습니다.UIWebView는 크기를 크제보대않지습다니고로 제대로 -[UIWebView sizeThatFits:]또한, https://stackoverflow.com/a/3937599/9636, 에서 언급한 바와 같이, 당신은 다음을 설정해야 합니다.UIWebViewframe height적당한 높이를 얻기 위해 1까지.

에 약에만.UIWebView의 높이가 너무 큽니다(즉, 1000으로 설정되었지만 HTML 콘텐츠 크기는 500에 불과함).

UIWebView.scrollView.contentSize.height
-[UIWebView stringByEvaluatingJavaScriptFromString:@"document.height"]
-[UIWebView sizeThatFits:]

a를 합니다.height천의

이 경우 제 문제를 해결하기 위해, 저는 https://stackoverflow.com/a/11770883/9636, 을 사용했고, 이는 제가 의무적으로 투표한 것입니다.그러나 이 솔루션은 다음과 같은 경우에만 사용합니다.UIWebView.frame.width는 와동합다니와 .-[UIWebView sizeThatFits:] width.

여기 제안된 어떤 것도 제 상황에 도움이 되지 않았지만, 저는 제게 답을 주는 것을 읽었습니다.고정된 UI 컨트롤 세트와 UI WebView가 있는 View 컨트롤러가 있습니다.UI 컨트롤이 HTML 콘텐츠에 연결된 것처럼 전체 페이지가 스크롤되기를 원했기 때문에 UI WebView에서 스크롤을 비활성화한 다음 상위 스크롤 뷰의 콘텐츠 크기를 올바르게 설정해야 합니다.

중요한 팁은 UI WebView가 화면에 렌더링될 때까지 크기를 올바르게 보고하지 않는다는 것입니다.그래서 콘텐츠를 로드할 때 콘텐츠 크기를 사용 가능한 화면 높이로 설정합니다.그런 다음 viewDidAppear에서 스크롤 보기의 콘텐츠 크기를 올바른 값으로 업데이트합니다.제가 로드를 호출하고 있기 때문에 이것은 저에게 효과가 있었습니다.로컬 콘텐츠에 HTML 문자열이 있습니다.loadRequest를 사용하는 경우 html을 검색하는 속도에 따라 webViewDidFinishLoad의 contentSize도 업데이트해야 할 수 있습니다.

스크롤 보기의 보이지 않는 부분만 변경되므로 깜박임이 없습니다.

HTML에 iframe의 내용(예: facebook-, twitter, instagram-embeds)과 같은 무거운 HTML 내용이 포함되어 있다면, 실제 솔루션은 훨씬 더 어렵습니다. 먼저 HTML을 포장하십시오.

[htmlContent appendFormat:@"<html>", [[LocalizationStore instance] currentTextDir], [[LocalizationStore instance] currentLang]];
[htmlContent appendFormat:@"<head>"];
[htmlContent appendString:@"<script type=\"text/javascript\">"];
[htmlContent appendFormat:@"    var lastHeight = 0;"];
[htmlContent appendFormat:@"    function updateHeight() { var h = document.getElementById('content').offsetHeight; if (lastHeight != h) { lastHeight = h; window.location.href = \"x-update-webview-height://\" + h } }"];
[htmlContent appendFormat:@"    window.onload = function() {"];
[htmlContent appendFormat:@"        setTimeout(updateHeight, 1000);"];
[htmlContent appendFormat:@"        setTimeout(updateHeight, 3000);"];
[htmlContent appendFormat:@"        if (window.intervalId) { clearInterval(window.intervalId); }"];
[htmlContent appendFormat:@"        window.intervalId = setInterval(updateHeight, 5000);"];
[htmlContent appendFormat:@"        setTimeout(function(){ clearInterval(window.intervalId); window.intervalId = null; }, 30000);"];
[htmlContent appendFormat:@"    };"];
[htmlContent appendFormat:@"</script>"];
[htmlContent appendFormat:@"..."]; // Rest of your HTML <head>-section
[htmlContent appendFormat:@"</head>"];
[htmlContent appendFormat:@"<body>"];
[htmlContent appendFormat:@"<div id=\"content\">"]; // !important https://stackoverflow.com/a/8031442/1046909
[htmlContent appendFormat:@"..."]; // Your HTML-content
[htmlContent appendFormat:@"</div>"]; // </div id="content">
[htmlContent appendFormat:@"</body>"];
[htmlContent appendFormat:@"</html>"];

그런 다음 x-update-webview-height-scheme 처리를 shouldStartLoadWithRequest에 추가합니다.

    if (navigationType == UIWebViewNavigationTypeLinkClicked || navigationType == UIWebViewNavigationTypeOther) {
    // Handling Custom URL Scheme
    if([[[request URL] scheme] isEqualToString:@"x-update-webview-height"]) {
        NSInteger currentWebViewHeight = [[[request URL] host] intValue];
        if (_lastWebViewHeight != currentWebViewHeight) {
            _lastWebViewHeight = currentWebViewHeight; // class property
            _realWebViewHeight = currentWebViewHeight; // class property
            [self layoutSubviews];
        }
        return NO;
    }
    ...

그리고 마지막으로 레이아웃 내에 다음 코드를 추가합니다.Subviews:

    ...
    NSInteger webViewHeight = 0;

    if (_realWebViewHeight > 0) {
        webViewHeight = _realWebViewHeight;
        _realWebViewHeight = 0;
    } else {
        webViewHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"content\").offsetHeight;"] integerValue];
    }

    upateWebViewHeightTheWayYorLike(webViewHeight);// Now your have real WebViewHeight so you can update your webview height you like.
    ...

추신: 목표 C/Swift-code 내에서 시간 지연(SetTimeout 및 setInterval)을 구현할 수 있습니다. 사용자에게 달려 있습니다.

추신: UI WebView 및 Facebook Embeddes에 대한 중요한 정보: 내장 Facebook 게시물이 UI WebView에 제대로 표시되지 않습니다.

스크롤 뷰에서 웹 뷰를 하위 뷰로 사용할 때 높이 제약 조건을 일정한 값으로 설정한 다음 나중에 해당 값에서 배출구를 만들어 다음과 같이 사용할 수 있습니다.

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    webView.scrollView.scrollEnabled = NO;
    _webViewHeight.constant = webView.scrollView.contentSize.height;
}

이상해요!

을 모두 테스트했습니다.sizeThatFits:그리고.[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"]나를 위해 일하지 않습니다.

하지만, 저는 웹 페이지 콘텐츠의 적절한 높이를 얻는 흥미롭고 쉬운 방법을 발견했습니다.현재 대리인 방식으로 사용하고 있습니다.scrollViewDidScroll:.

CGFloat contentHeight = scrollView.contentSize.height - CGRectGetHeight(scrollView.frame);

iOS 9.3 시뮬레이터/디바이스에서 확인되었습니다. 행운을 빕니다!

편집:

파일: content template로 되며, method 파일을 로드합니다.loadHTMLString:baseURL:등록된 JS 스크립트가 없습니다.

저도 이 문제에 몰두하고 있는데, 웹뷰의 동적 높이를 계산하려면 먼저 웹뷰의 너비를 알려줘야 한다는 것을 깨달았습니다. 그래서 js 앞에 한 줄을 추가하면 매우 정확한 실제 높이를 얻을 수 있습니다.

코드는 다음과 같이 간단합니다.

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

    //tell the width first
    webView.width = [UIScreen mainScreen].bounds.size.width;

    //use js to get height dynamically
    CGFloat scrollSizeHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
    webView.height = scrollSizeHeight;

    webView.x = 0;
    webView.y = 0;

    //......
}

Xcode8 swift3.1:

  1. 먼저 webView 높이를 0으로 설정합니다.
  2. webViewDidFinishLoad대리인:

let height = webView.scrollView.contentSize.height

웹 뷰의 경우 1단계가 없습니다.높이 > 실제 내용높이, 2단계에서 웹 보기를 반환합니다.높이만 내용 크기가 아닙니다.높이.

이 뷰 에 추가합니다.viewDidLoad방법:

if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) {
    self.automaticallyAdjustsScrollViewInsets = NO;
}

그렇지 않으면 두 가지 방법 모두 제대로 작동하지 않을 것입니다.

언급URL : https://stackoverflow.com/questions/3936041/how-to-determine-the-content-size-of-a-uiwebview

반응형