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
전하기전틀화를 전의 sizeThatFits
CGSizeZero
매개변수 저는 이 이 "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
하지만 그것은 나의 것을 요약하는 것만큼 쉬웠습니다.webView
의frame.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, 에서 언급한 바와 같이, 당신은 다음을 설정해야 합니다.UIWebView
의frame
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:
- 먼저 webView 높이를 0으로 설정합니다.
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
'prosource' 카테고리의 다른 글
C 및 C++에서 인덱스[어레이]로 어레이 액세스 (0) | 2023.06.07 |
---|---|
다중 처리 : tqdm을 사용하여 진행률 표시줄 표시 (0) | 2023.06.07 |
Firebase Messaging에서 모든 항목을 한 번에 구독 취소 (0) | 2023.06.07 |
Python 3.6.1에서 AttributeError가 발생하는 이유: 모듈 'enum'에는 'IntFlag' 속성이 없습니까? (0) | 2023.06.02 |
인스턴스 변수: 자체 vs @ (0) | 2023.06.02 |