मेरे पास UIWebView
अलग (एकल पृष्ठ) सामग्री है। मैं CGSize
अपने माता-पिता के विचारों को उचित रूप से बदलने के लिए सामग्री का पता लगाना चाहता हूं । स्पष्ट रूप से -sizeThatFits:
दुर्भाग्य से अभी webView का वर्तमान फ्रेम आकार वापस आ गया है।
मेरे पास UIWebView
अलग (एकल पृष्ठ) सामग्री है। मैं CGSize
अपने माता-पिता के विचारों को उचित रूप से बदलने के लिए सामग्री का पता लगाना चाहता हूं । स्पष्ट रूप से -sizeThatFits:
दुर्भाग्य से अभी webView का वर्तमान फ्रेम आकार वापस आ गया है।
जवाबों:
यह पता चला कि मेरा पहला अनुमान -sizeThatFits:
पूरी तरह से गलत नहीं था। यह काम करने लगता है, लेकिन केवल अगर webView का फ्रेम भेजने से पहले न्यूनतम आकार में सेट किया गया है -sizeThatFits:
। उसके बाद हम फिटिंग साइज के हिसाब से गलत फ्रेम साइज को सही कर सकते हैं। यह भयानक लगता है लेकिन यह वास्तव में उतना बुरा नहीं है। चूँकि हम दोनों फ्रेम एक दूसरे के ठीक बाद बदलते हैं, दृश्य अपडेट नहीं होता है और न ही झिलमिलाता है।
बेशक, हमें सामग्री को लोड होने तक इंतजार करना होगा, इसलिए हमने कोड को -webViewDidFinishLoad:
प्रतिनिधि विधि में डाल दिया ।
Obj सी
- (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
}
मुझे इंगित करना चाहिए कि जावास्क्रिप्ट का उपयोग करके एक और दृष्टिकोण (धन्यवाद @GregInYEG) है। निश्चित नहीं है कि कौन सा समाधान बेहतर प्रदर्शन करता है।
दो हैकी समाधानों में से मुझे यह एक बेहतर लगता है।
UIWebView
आपका पैरेंट व्यू से अधिक है, तो आपको इसे एंबेड करना होगा UIScrollView
।
मेरे पास एक और उपाय है जो बढ़िया काम करता है।
एक तरफ, ऑर्टविन का दृष्टिकोण और समाधान केवल iOS 6.0 और बाद के संस्करण के साथ काम करता है, लेकिन iOS 5.0, 5.1 और 5.1.1 पर सही ढंग से काम करने में विफल रहता है, और दूसरी ओर कुछ ऐसा है जो मुझे पसंद नहीं है और समझ नहीं सकता है ऑर्टविन के दृष्टिकोण के साथ, यह [webView sizeThatFits:CGSizeZero]
पैरामीटर के साथ विधि का उपयोग है CGSizeZero
: यदि आप इस तरीके और इसके पैरामीटर के बारे में Apple आधिकारिक दस्तावेज पढ़ते हैं, तो यह स्पष्ट रूप से कहता है:
इस पद्धति का डिफ़ॉल्ट कार्यान्वयन दृश्य के सीमा आयत के आकार के हिस्से को वापस लौटाता है। उप-वर्ग किसी भी साक्षात्कार के वांछित लेआउट के आधार पर एक कस्टम मान वापस करने के लिए इस पद्धति को ओवरराइड कर सकते हैं। उदाहरण के लिए, एक UISwitch ऑब्जेक्ट एक निश्चित आकार मान देता है जो एक स्विच दृश्य के मानक आकार का प्रतिनिधित्व करता है, और एक UIImageView ऑब्जेक्ट उस छवि का आकार लौटाता है जो वर्तमान में प्रदर्शित हो रहा है।
मेरा मतलब यह है कि यह ऐसा है जैसे वह बिना किसी तर्क के अपने समाधान में आया था, क्योंकि दस्तावेज़ीकरण को पढ़ते हुए, पैरामीटर [webView sizeThatFits: ...]
को कम से कम वांछित होना चाहिए width
। उसके समाधान के साथ, पैरामीटर के साथ webView
कॉल sizeThatFits
करने से पहले वांछित चौड़ाई सेट की जाती है CGSizeZero
। इसलिए मैं इस समाधान को "मौका" द्वारा iOS 6 पर काम कर रहा हूं।
मैंने अधिक तर्कसंगत दृष्टिकोण की कल्पना की, जिसमें आईओएस 5.0 और बाद के लिए काम करने का लाभ है ... और उन जटिल परिस्थितियों में भी जहां एक से अधिक वेबव्यू (इसकी संपत्ति webView.scrollView.scrollEnabled = NO
में एम्बेडेड है) scrollView
।
यहाँ मेरा कोड webView
वांछित के लेआउट को मजबूर करने width
और संबंधित height
सेट को वापस webView
स्वयं प्राप्त करने के लिए है:
Obj सी
- (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
इन embedding webViews
, लेकिन यह आसान के रूप में था संक्षेप के रूप में मेरे webView
's frame.size.height
चाल के साथ गणना की ऊपर वर्णित ...
-[UIWebView scrollView]
iOS 5.0 या बाद के संस्करण में ही उपलब्ध है।
इस सवाल को फिर से ज़िंदा करना क्योंकि मुझे उस समय के ज्यादातर कामों के लिए ऑर्टविन का जवाब मिला ...
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;
}
स्विफ्ट (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
}
}
अद्यतन: मैंने पाया है कि टिप्पणियों में उल्लेख किया गया है कि यह उस मामले को पकड़ता नहीं है जहां सामग्री सिकुड़ गई है। यकीन नहीं है कि यह सभी सामग्री और ओएस संस्करण के लिए सच है, इसे आज़माएं।
webView.scalesPageToFit = YES
ऊपर दिए गए टिप्पणी में उल्लिखित @Sijo के रूप में नहीं देते हैं।
एक वेब दृश्य की ऊंचाई निर्धारित करने के लिए Xcode 8 और iOS 10 में। आप ऊंचाई का उपयोग कर प्राप्त कर सकते हैं
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
NSLog(@"Webview height is:: %f", height);
}
या स्विफ्ट के लिए
func webViewDidFinishLoad(aWebView:UIWebView){
let height: Float = (aWebView.stringByEvaluatingJavaScriptFromString("document.body.scrollHeight")?.toFloat())!
print("Webview height is::\(height)")
}
एक सरल समाधान सिर्फ उपयोग करना होगा, webView.scrollView.contentSize
लेकिन मुझे नहीं पता कि यह जावास्क्रिप्ट के साथ काम करता है या नहीं। यदि कोई जावास्क्रिप्ट नहीं है, तो यह सुनिश्चित करने के लिए इस कार्य का उपयोग करता है:
- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
CGSize contentSize = aWebView.scrollView.contentSize;
NSLog(@"webView contentSize: %@", NSStringFromCGSize(contentSize));
}
यह अजीब है!
मैं समाधान का परीक्षण दोनों sizeThatFits:
और [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"]
कर रहे हैं नहीं मेरे लिए काम कर।
हालांकि, मुझे वेबपेज सामग्री की सही ऊंचाई पाने के लिए एक दिलचस्प आसान तरीका मिला। वर्तमान में, मैंने इसे अपने प्रतिनिधि पद्धति में उपयोग किया scrollViewDidScroll:
।
CGFloat contentHeight = scrollView.contentSize.height - CGRectGetHeight(scrollView.frame);
आईओएस 9.3 सिम्युलेटर / डिवाइस में सत्यापित, अच्छी किस्मत!
संपादित करें:
पृष्ठभूमि: html सामग्री की गणना मेरे स्ट्रिंग चर और HTTP सामग्री टेम्पलेट द्वारा की जाती है loadHTMLString:baseURL:
, जो विधि द्वारा लोड की जाती है , कोई पंजीकृत JS स्क्रिप्ट नहीं है।
मैं एक का उपयोग कर रहा हूँ UIWebView
कि एक सबव्यू नहीं है (और इस तरह विंडो पदानुक्रम का हिस्सा नहीं है) के लिए HTML सामग्री का आकार निर्धारित करने के लिए UITableViewCells
। मैंने पाया कि डिस्कनेक्ट किया गया UIWebView
आकार इसके साथ ठीक से रिपोर्ट नहीं करता है -[UIWebView sizeThatFits:]
। इसके अतिरिक्त, जैसा कि https://stackoverflow.com/a/3937599/9636 में बताया गया है , आपको उचित ऊँचाई प्राप्त करने के लिए UIWebView
's' frame
height
को 1 पर सेट करना होगा ।
यदि आपकी UIWebView
ऊंचाई बहुत बड़ी है (अर्थात आपने इसे 1000 पर सेट किया है, लेकिन HTML सामग्री का आकार केवल 500 है):
UIWebView.scrollView.contentSize.height
-[UIWebView stringByEvaluatingJavaScriptFromString:@"document.height"]
-[UIWebView sizeThatFits:]
सभी height
1000 की वापसी ।
इस मामले में मेरी समस्या को हल करने के लिए, मैंने https://stackoverflow.com/a/11770883/9636 का उपयोग किया , जिसे मैंने कर्तव्यपूर्वक वोट दिया। हालाँकि, मैं केवल इस समाधान का उपयोग करता हूं जब मेरा UIWebView.frame.width
समान है -[UIWebView sizeThatFits:]
width
।
यहां किसी भी सुझाव ने मेरी स्थिति के साथ मेरी मदद नहीं की, लेकिन मैंने कुछ पढ़ा, जिसने मुझे जवाब दिया। मेरे पास UICebView के बाद UI नियंत्रणों के एक निश्चित सेट के साथ एक ViewController है। मैं संपूर्ण पृष्ठ को स्क्रॉल करना चाहता था जैसे कि UI नियंत्रण HTML सामग्री से जुड़े थे, इसलिए मैं UIWebView पर स्क्रॉल अक्षम करता हूं और फिर एक माता-पिता स्क्रॉल दृश्य की सामग्री का आकार सही ढंग से सेट करना चाहिए।
महत्वपूर्ण टिप यह निकला कि UIWebView स्क्रीन को प्रस्तुत करने तक इसके आकार को सही ढंग से रिपोर्ट नहीं करता है। इसलिए जब मैं सामग्री लोड करता हूं तो मैं उपलब्ध स्क्रीन ऊंचाई पर सामग्री का आकार निर्धारित करता हूं। फिर, viewDidAppear में मैं स्क्रॉलव्यू की सामग्री के आकार को सही मान पर अद्यतन करता हूं। इसने मेरे लिए काम किया क्योंकि मैं स्थानीय सामग्री पर loadHTMLString कह रहा हूं। यदि आप loadRequest का उपयोग कर रहे हैं, तो आपको webViewDidFinishLoad में भी सामग्री को अपडेट करने की आवश्यकता हो सकती है, यह इस बात पर निर्भर करता है कि HTML कितनी जल्दी पुनर्प्राप्त होता है।
कोई चंचलता नहीं है, क्योंकि स्क्रॉल दृश्य के केवल अदृश्य भाग को बदल दिया जाता है।
webViewDidFinishLoad
सुरक्षित दृष्टिकोण के रूप में भरोसा करता हूं ।
यदि आपके HTML में iframe की तरह भारी HTML-सामग्री है (यानी facebook-, ट्विटर, इंस्टाग्राम-एम्बेड) वास्तविक समाधान अधिक कठिन है, तो पहले अपने 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 को जोड़ने के लिए अपने stStartLoadWithRequest को जोड़ें :
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;
}
...
और अंत में निम्न कोड अपने अंदर जोड़ने layoutSubviews :
...
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.
...
PS आप अपने ObjectiveC / Swift- कोड के अंदर देरी (SetTimeout और setInterval) को लागू कर सकते हैं - यह आपके ऊपर है।
PSS UIWebView और फेसबुक एंबेड्स के बारे में महत्वपूर्ण जानकारी: एंबेडेड फेसबुक पोस्ट UIWebView में ठीक से नहीं दिखाता है
स्क्रॉलव्यू में कहीं-कहीं सबव्यू के रूप में वेबव्यू का उपयोग करते समय, आप कुछ स्थिर मान के लिए ऊँचाई की बाधा निर्धारित कर सकते हैं और बाद में इससे आउटलेट बना सकते हैं और इसका उपयोग कर सकते हैं:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
webView.scrollView.scrollEnabled = NO;
_webViewHeight.constant = webView.scrollView.contentSize.height;
}
मैं भी इस समस्या पर अटका हुआ हूं, तब मुझे महसूस हुआ कि अगर मैं वेब व्यू की गतिशील ऊंचाई की गणना करना चाहता हूं, तो मुझे पहले वेब व्यू की चौड़ाई बताने की जरूरत है, इसलिए मैं जेएस से पहले एक लाइन जोड़ता हूं और यह पता चला है कि मैं प्राप्त कर सकता हूं बहुत सटीक वास्तविक ऊंचाई।
कोड इस तरह सरल है:
-(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 स्विफ्ट 3.1:
webViewDidFinishLoad
प्रतिनिधि:let height = webView.scrollView.contentSize.height
Step1 के बिना, यदि webview.height> वास्तविक contentHeight, चरण 2 webview.height वापस आ जाएगा, लेकिन नहीं सामग्री।
सभी उल्लिखित विधियों के उचित कार्य के लिए iOS 7 में भी इसे अपने व्यू कंट्रोलर viewDidLoad
विधि में जोड़ें :
if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) {
self.automaticallyAdjustsScrollViewInsets = NO;
}
अन्यथा न तो तरीके के रूप में यह काम करना चाहिए।