I know this question was posted so many times but still I can not change the height of UIWebView based on its content
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title=#"webview";
[_webView setDelegate:self];
NSString * string = #"<h1>This is HTML string</h1>";
[_webView loadHTMLString:string baseURL:nil];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
NSLog(#"start loadinng.......");
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"finish loading.......");
CGRect frame = _webView.frame;
frame.size.height = 1;
_webView.frame = frame;
CGSize fittingSize = [_webView sizeThatFits:CGSizeZero];
frame.size = fittingSize;
_webView.frame = frame;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(#"Failed to load with error :%#",[error debugDescription]);
}
can anybody help me how can resize my UIWebView height?
Here is your answer.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (webView.isLoading){
return;
}
CGSize contentSize = webView.scrollView.contentSize;
NSLog (#"height: %f",contentSize.height);
}
After gettting this height reframe your webView with new width and height and also reframe its parent view if there any.
How about this.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView sizeToFit];
webView.frame = CGRectMake(x,y,width,webView.frame.size.height);
}
I usually use these methods, to set UIWebview frame as it's content size:
- (void)webViewDidStartLoad:(UIWebView *)webView
{
CGRect frame = webView.frame;
frame.size.height = 5.0f;
webView.frame = frame;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
CGSize mWebViewTextSize = [webView sizeThatFits:CGSizeMake(1.0f, 1.0f)]; // Pass about any size
CGRect mWebViewFrame = webView.frame;
mWebViewFrame.size.height = mWebViewTextSize.height;
webView.frame = mWebViewFrame;
//Disable bouncing in webview
for (id subview in webView.subviews)
{
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
{
[subview setBounces:NO];
}
}
}
They are automatically called (if you set webviews delegate to this class), when WebView has finished loading it's content.
or
check this
raywenderlich-tutorial
This might helps you :)
First calculate height of web view for desired content.
NSString* lString = #"<h1>This is HTML string</h1>";
NSAttributedString* lAttributedText = [[NSAttributedString alloc] initWithData: [lString dataUsingEncoding:NSUTF8StringEncoding]
options:#{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)
}
documentAttributes: nil
error:nil];
CGRect lBoundingRect = [lAttributedText boundingRectWithSize: CGSizeMake(_webView.bounds.size.width, CGFLOAT_MAX) options: NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context: nil];
then set it to _webView.frame
Now, load web view
[_webView setDelegate:self];
[_webView loadHTMLString: lString baseURL:nil];
Related
I want to zooming in out in WebView.I am newer in iOS.Please Help me.Some one say it is default property of WebView.I am testing in iOS8 . It does not work for me.
self.myWebView= [[UIWebView alloc] init];
[self.myWebView setScalesPageToFit:YES];
[self.myWebView setDelegate:self];
[self.myWebView.scrollView setDelegate:self];
[self.myWebView setDataDetectorTypes:UIDataDetectorTypeNone];
[self.myWebView.scrollView setBounces:NO];
[self.myWebView.scrollView setShowsHorizontalScrollIndicator:NO];
[self.myWebView.scrollView setShowsVerticalScrollIndicator:NO];
[myScrollView addSubview:self.myWebView];
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
self.myWebView.scrollView.delegate = self;
self.myWebView.scrollView.maximumZoomScale = 20; // set as you want.
self.myWebView.scrollView.minimumZoomScale = 1; // set as you want.
}
(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
self.myWebView.scrollView.maximumZoomScale = 20;
}
if u are not use viewForZoomingInScrollView they work automatically. if you are use viewForZoomingInScrollView
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
if (scrollView ==myWebView.scrollView){
return self.myWebView;
}
else
{
return nil;
}
}
I came to a point where I was able to lock the horizontal scroll as I wanted however when I rotate from landscape to portrait the content is still to large. I need to resize/scale it down myself but I don't know how to so far I use this :
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *fullURL = #"http://igo.nl";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView loadRequest:requestObj];
_webView.scrollView.bounces = false;
_webView.scalesPageToFit = YES;
_webView.contentMode = UIViewContentModeScaleAspectFit;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if(fromInterfaceOrientation == UIInterfaceOrientationPortrait)
{
//_webView.scrollView.contentSize = CGSizeMake(320, _webView.scrollView.contentSize.height);
}
else
{
//[_webView reload];
_webView.bounds = CGRectMake(0, 0, 320,_webView.bounds.size.height);
_webView.frame = CGRectMake(0, 0, 320, _webView.frame.size.height);
_webView.scrollView.contentSize = CGSizeMake(320, _webView.scrollView.contentSize.height);
}
}
EDIT:
What I seem to need is that the content is zoomed out
Use the delegate methods of UIWebViewDelegate
#interface YOUR_CLASS : PARENT_CLASS <UIWebViewDelegate>
In viewDidLoad
...
[_webView setDelegate:self];
...
Call the delegate method
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView.scrollView setContentSize: CGSizeMake(webView.frame.size.width, webView.scrollView.contentSize.height)];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[_webView reload]; //Or use meta tag
[_webView.scrollView setContentSize: CGSizeMake([_webView.scrollView.contentSize.width, _webView.scrollView.contentSize.height)];
}
You have to add meta tag to your HTML file
<meta name="viewport" content="width=device-width" />
or simply reload the webView
[_webView reload];
try in
-(void)viewWillLayoutSubviews
{
------
}
calculate using
self.view.bounds.size.width,
self.view.bounds.size.height
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation==UIInterfaceOrientationPortrait && toInterfaceOrientation!=UIInterfaceOrientationPortraitUpsideDown )
{
}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation ==UIInterfaceOrientationLandscapeRight)
{
}
}
After load htmlString, contentSize of scrollView in UIWebView don't changed. In other my viewControllers all good, but now it's something mysterious
I have
UIWebView *contentWebView;
I make it in some method
- (void)makeContent
{
...
contentWebView = [[UIWebView alloc] initWithFrame:CGRectMake(5, imageView.originY + imageView.height + 5, mainView.width - 10, 100)];
contentWebView.delegate = self;
contentWebView.scrollView.scrollEnabled = NO;
contentWebView.contentMode = UIViewContentModeScaleAspectFit;
NSLog(#"%#", factDict[#"text"]);
[contentWebView loadHTMLString:factDict[#"text"] baseURL:nil];
contentWebView.height = contentWebView.scrollView.contentSize.height;
[mainView addSubview:contentWebView];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"%f %f %f %f ", webView.height, webView.scrollView.contentSize.height, contentWebView.height, contentWebView.scrollView.contentSize.height);
[webView sizeToFit];
NSLog(#"%f %f %f %f ", webView.height, webView.scrollView.contentSize.height, contentWebView.height, contentWebView.scrollView.contentSize.height);
...
}
Early in other controllers contentWebView.height = contentWebView.scrollView.contentSize.height; help me, but now it's not work
In log I have next
So I don\t understand why contentsize.height not changed
EDIT
In my another viewcontrollers all good
- (void)makeScrollView
{
CGFloat width = [Utils widthOfMainViewForOrientation:self.interfaceOrientation];
[mainView removeFromSuperview];
mainView = [[UIView alloc] initWithFrame:CGRectMake((self.view.width - width) / 2, 15, width, 100)];
mainView.backgroundColor = [UIColor whiteColor];
if ([self.fullInfoDictionary[#"content"] length]) {
contentWebView = [[UIWebView alloc] initWithFrame:CGRectMake(6, 4, mainView.width - 12, 100)];
contentWebView.contentMode = UIViewContentModeScaleAspectFit;
contentWebView.delegate = self;
HelperDf.htmlString = self.fullInfoDictionary[#"content"];
[contentWebView loadHTMLString:self.fullInfoDictionary[#"content"] baseURL:nil];
contentWebView.scrollView.scrollEnabled = NO;
[mainView addSubview:contentWebView];
}
[self.scrollView addSubview:mainView];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
contentWebView.height = contentWebView.scrollView.contentSize.height;
NSLog(#"%f %f %f %f", webView.height, webView.scrollView.contentSize.height, contentWebView.height, contentWebView.scrollView.contentSize.height);
[self reloadFrames];
}
i have next
I get htmlString from this controller
HelperDf.htmlString = self.fullInfoDictionary[#"content"];
And set in my first UIWebVIew but results - NO.
You can it's no matter if stay contentWebView.scrollView.scrollEnabled = NO; I change to YES, but results are same - in second case all good in first - NO
You need to change NO to YES your contentWebView.scrollView.scrollEnabled, such like
contentWebView.scrollView.scrollEnabled = YES;
EDITED
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView sizeToFit];
webView.scrollView.contentSize = CGSizeMake(320, contentWebView.scrollView.contentSize.height + 60);
}
The problem is that your view isn't visible yet. The values you are looking for are only made visible once it is added to a view which is in the view stack.
Somewhere along the way it seems that your view isn't added to at the time when you are checking your values.
In web view my code is`static float i=1.5;
if(i<=7.5)
{
[btnZoom setEnabled:YES];
objWebView.transform = CGAffineTransformMakeScale(1+i,1+i);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.0f];
[UIView commitAnimations];
i=i+1.5;
NSLog(#"i===============%f",i);
}
if(i==7.5)
{
NSLog(#"i===============%f",i);
[btnZoom setEnabled:NO];
i=1.5;
}
objWebview is the object of web view.my scales page to fit property of webview is clicked but I have to zoom in on the button click. (I am new in iPhone)
By this code it is getting zoomed-in, but my webview contents are getting blurred when zoomed in.
There are two ways to zoom your UIWebView by codebase.
Zoom UIScrollView available in UIWebView
This option will applicable from iOS 5.0 and >
- (void)viewDidLoad
{
NSString *urlAddress = #"<website url address here>";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]
[webView loadRequest:requestObj];
webView.delegate = self;
webLookupView.scalesPageToFit = YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
CGSize contentSize = theWebView.scrollView.contentSize;
CGSize viewSize = self.view.bounds.size;
float rw = viewSize.width / contentSize.width;
theWebView.scrollView.minimumZoomScale = rw;
theWebView.scrollView.maximumZoomScale = rw;
theWebView.scrollView.zoomScale = rw;
}
Zoom Webpage itself
In UIWebViewDelegate method – webViewDidFinishLoad:
NSString *jsCommand = [NSString stringWithFormat:#"document.body.style.zoom = 1.5;"];
[theWebView stringByEvaluatingJavaScriptFromString:jsCommand];
Hope this helps you.
Suppose that I have a UIWebView that's stacked against a UIImageView (or some other view):
I want to resize my UIWebView so that I know where to put the UIImageView. The way I do it is to wait for the UIWebView to finish loading:
webViewCalculating = YES;
while (webViewCalculating == YES) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
Then I resize it when the UIWebView has finished loading, according to 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;
}
After this point, I'd know how tall my UIWebView is, and I can place my UIImageView accordingly. However when I push another view controller and came back to this, my hacky [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode doesn't seem to wait until my webView finished calculating the height first. Is there a better way for me to know the size of my UIWebView without waiting for it to load? Maybe something similar to sizeWithFont method of NSString?
You should not be doing your while loop that is pumping the run-loop. This is a very bad idea. You should have your scroll view container respond and relayout the subviews when the webview finishes loading. Start with a "reasonably sized webview area". Maybe show a spinner in pace while the web content is loading.
A technique I've used to do exactly this is as follows:
Firstly add some category methods to UIWebView as follows:
#interface UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight;
#end
#implementation UIWebView (ContentSize)
- (CGFloat)documentOffsetHeight
{
return [[self stringByEvaluatingJavaScriptFromString:#"document.documentElement.offsetHeight"] floatValue];
}
#end
Then I've written a UIView subclass that contains the UIWebView. Eg:
#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
So basically what this UIView subclass does is embed an invisible _webview. Then when the document has loaded and rendered the jQuery based JavaScript tries to navigate away from the current page using a custom URL scheme. This navigation is trapped an denied. But in response the view sizes to fit and gets the proper size from the HTML document.
Note that you don't have to use jQuery. You can add a DOM JavaScript event. I'm just more familiar with how jQuery does things that raw DOM events.
In your case you would have to communicate to the scrollview that the content has finished loading and that the scroll view views should re-layout. You can do this with a delegate protocol or something similar. Or maybe the scrollview is the "MyWebView" container UIView subclass. Adapt as needed.
properties are not reset, so when you come back to this controller you need to webViewCalculating = YES;
so that it doesn't instantly fail the while loop.
If you are already doing that you could try putting
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
with in the
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
}
delegate method
Hope this is useful.