How to always show last page of the UIWebView - ios

i am using UIWebview as a console page for particular downloading process ,i want to show last line or last page of UIWebview like console. so please tell any methods there for that.i am adding text to UIWebview different places using following code [webView loadHTMLString:theApp.consoleUpdaterStr baseURL:nil];

try to set contentOffset
- (void)webViewDidFinishLoad:(UIWebView *)webView {
myWebView.scrollView.contentOffset = CGPointMake(0, CGFLOAT_MAX);
}

try this :
CGPoint bottomOffset = CGPointMake(0, myWebview.scrollView.contentSize.height - myWebview.scrollView.bounds.size.height);
[myWebview.scrollView setContentOffset:bottomOffset animated:YES];

try this
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
myWebView.scrollView.contentOffset = CGPointMake(0, CGFLOAT_MAX);
}

Related

UIWebView "document.height" evaluation returns wrong height on older iphones (specifically 4s and 5)

The problem is that, i have a tableview with several cells, and have a webView in one of these cells. By disabling the scroll on the webview, i should have a static web content view scrolling in the tableView, not by itself, which all works great.
In the webViewDidFinishLoad method i call
[[webView stringByEvaluatingJavaScriptFromString: #"document.height"] floatValue];
then set this value in heightForRowAtIndexPath by reloading the table. It all works great on iPhone 6 and up, but on 4s and 5, the bottom of my web content is clipped off. The returned height difference is completely random, with 724 pixel height being unclipped and fine, on other content with nearly the same returned pixel height cut off by more than 30% percent of the original.
I tried several approaches that i found here, but none of them worked.
Tried to get the max value from evaluating the offsetheight, scrollheight and other properties, but also without success.
Also tried running jquery commands on my webview, but again, without success so far.
If anyone has any experience with a problem like this, please help.
The full code snippet, where "articleViewHeight" is a constraint for the mentioned webView:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return [self getCellHeight:indexPath.row];
}
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self getCellHeight:indexPath.row];
}
-(CGFloat)getCellHeight:(NSInteger)row{
switch (row) {
case 0:
return self.view.frame.size.height * 0.1f;
break;
case 1:
return self.view.frame.size.height * 0.375f;
break;
case 2:
return UITableViewAutomaticDimension;//self.view.frame.size.height * 0.15f;
break;
case 3:
return self.articleViewHeight;
break;
case 4:
return self.view.frame.size.height * 0.2f;
break;
default:
return UITableViewAutomaticDimension;
break;
}
}
- (void)webViewDidFinishLoad:(UIWebView * _Nonnull)webView{
CGFloat height = [self getWebViewPageHeight];
self.articleViewHeight = height;
[self.tableView reloadData];
[self removeLoader];
}
- (CGFloat) getWebViewPageHeight {
CGFloat height1 = [[self.articleView stringByEvaluatingJavaScriptFromString: #"document.height"] floatValue];
CGFloat height2 = [[self.articleView stringByEvaluatingJavaScriptFromString: #"document.body.scrollHeight"] floatValue];
return MAX(height1, height2);
}
Update: the htmlstring loading code as requested
-(void)doneLoading{
NSString *pathToFile =[[NSBundle mainBundle] pathForResource:#"news" ofType:#"css"];
NSString *fileString = [NSString stringWithContentsOfFile:pathToFile encoding:NSUTF8StringEncoding error:nil];
NSString* headerString = #"<!DOCTYPE html><html><head title='test'><style type=\"text/css\" media=\"all\">%#</style></head><body><div id='content'>%#</div></body></html>";
NSString * theString = [NSString stringWithFormat:headerString,fileString,self.htmlString];
[self.articleView loadHTMLString:theString baseURL:nil];
}
This solution works only for local html string which you can freely modify (well, you could download webpage separately into a string and inject this but then you get a load of other problems.
I've had similar problem and found following method to solve them. First of all, add this script in the <head> tag of your html.
<script type="text/javascript">
window.onload = function(){
window.location.href = "height://"+document.getElementById("content").offsetHeight;
}
</script>
This is needed because when - (void)webViewDidFinishLoad:(UIWebView *)webView; is called the content still may not have correct height. Also, put all your html content into one div with id from the script ("content" int this example).
... html header
<body>
<div id="content">
... your content
</div>
</body>
Then modify your - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; method.
-(BOOL)webView:(UIWebView*)pWebView shouldStartLoadWithRequest:(NSURLRequest*)pRequest navigationType:(UIWebViewNavigationType)pNavigationType{
NSURL* url = pRequest.URL;
if(pNavigationType==UIWebViewNavigationTypeLinkClicked){
return ![[UIApplication sharedApplication] openURL:url];
// or do whatever you do with normal links
} else if([url.scheme isEqualToString:#"height"]){
CGFloat contentHeight = [url.host floatValue];
// do your thing with height
}
}
And viola! This made it for me. Any height error was so marginal that adding small (2px) additional bottom padding for content in CSS completely shown my content.
EDIT:
I just noticed important thing in my code. The webview have .scaleToPage flag set to NO and even more important: initial height of webview. It's set to 6k. If I change it to 0, sure enought, the content is cut after loading.
So to get correct height, the initial height of wevbiew during loading must be big enough to store whole html content without scrolling.
Since you have your webview in a cell, this won't help you. So maybe put another, hidden and big webview on the bottom of drawing stack, with same width as the one in the cell and load your conent there first, get height and then load the one in a cell.
I have had a requirement to have web view in scrollview.
The way I handled, tested without any hack. Actually this delegate method is called multiple times in a single request. Your webViewDidFinishLoad must be like below:
There is a delegate - (void)webViewDidFinishLoad:(UIWebView *)webView
I calculate web view height:-
- (void)webViewDidFinishLoad:(UIWebView *)webView{
if (webView.isLoading == NO)// as it is called multiple times so wait untill last call
{
NSDictionary* userInfo = #{#"webView": webView};
[[NSNotificationCenter defaultCenter] postNotificationName:WEB_VIEW_FINISH_LOAD object:nil userInfo:userInfo];//sending to compute content size for any view which is using this class
}
[self hideActivityOverlayAnimation:NO];
}
This is how i have computed web view height:
-(void)webViewFinishedLoad:(NSNotification*)notification{
if ([notification.name isEqualToString:WEB_VIEW_FINISH_LOAD])
{
NSDictionary* userInfo = notification.userInfo;
UIWebView* webView = (UIWebView*)userInfo[#"webView"];
[webView.scrollView setScrollEnabled:NO];// it was my requirement, dont have to do any thing with height calculation
CGFloat **height** = [[webView stringByEvaluatingJavaScriptFromString:#"document.height"] floatValue];//every time it returnes different
}
}
You can use this height to resize your cell height.
The main part which puzzle me was above. My set Up method of web view:
self.webView = [[UIWebView alloc] initWithFrame:webViewFrame];
[self.webView setDelegate:self];
self.webView.scalesPageToFit = YES;
self.webView.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:self.webView];
Hope it will help you !!!

Unable to fit webpage in UIWebView in ios?

I am displaying a webpage in UIWebview. My webpage looks good on the browser, but on iPhone 5s the view does not fit. It is much too large, so I want to know how I can fit the content.
I have used ScalePageToFit & sizeTofit but nothing is working.
set your web view delegate and frame.
yourwebview.frame=[[UIScreen mainScreen] bounds];
yourwebview.delegate = self;
end then use this delegate method to set height.
- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
CGSize contentSize = aWebView.scrollView.contentSize;
NSLog(#"webView contentSize: %#", NSStringFromCGSize(contentSize));
yourwebview.contentsize = contentSize;
}
OR
also See my answer at How to make iOS UIWebView display a mobile website correctly?
lets try this, some web pages doesn't responds to scalesPageToFit try this not sure , just give it a try
//those web pages can handle only once the web page is loaded completely
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if ([_webView respondsToSelector:#selector(scrollView)])
{
UIScrollView *scroll = [_webView scrollView];
float zoom = ((_webView.bounds.size.width + 20 )/scroll.contentSize.width) - 0.30;
[scroll setZoomScale:zoom animated:YES];
}
}

iOS UIWebView shown just part of content in UIScrollView

I would like to have UIImage and UIWebView in UIScrollView so when I scroll first it would disappear image and then I would scroll with just webView. So I set it in storyboard and I added these methods to my code:
- (void)setScrollViewContentSize
{
float sizeOfContent = 0;
UIView *lLast = [_scrollView.subviews objectAtIndex:1];
NSInteger wd = lLast.frame.origin.y;
NSInteger ht = lLast.frame.size.height;
sizeOfContent = wd+ht;
_scrollView.contentSize = CGSizeMake(_scrollView.frame.size.width, sizeOfContent);
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[webView sizeToFit];
[webView setFrame:CGRectMake(webView.frame.origin.x, webView.frame.origin.y, webView.frame.size.width, webView.frame.size.height)];
[self setScrollViewContentSize];
}
It's working just with one problem. When I scroll for a few lines I get new content of webView but after that I don't see anything. I think it has something to do with cache and that I am not scrolling in webView but with scrollView and so webView doesn't know that it should display that content. Anyone could help? Thanks

Get height of UIWebView loaded content

So what I am after is a way to put a UIButton on top of a UIScrollView and a UIWebView under it. The reason I want it this way is that I need the button to "scroll away" as the user scrolls the page I load into the UIWebView.
In order for this to work, I need to get the height of the content of the web page I load and then set the height of the web view to match this. If I can do this, I then intend to set the contentSize of the UIScrollView to match the heights of the button and web view.
I understand that somehow this is supposed to happen in the - (void)webViewDidStartLoad:(UIWebView *)webView method, which is confirmed on many threads on stackoverflow (for example this one). I also know that Apple says you shouldn't put a UiWebView in a UIScrollView, since the scrolling actions may interfere. Disabling scroll for the web view should avoid the problem though.
There are many threads discussing this matter, but none of them seem to work for me. Can it be because I am running on iOS7?
I am in big desperation here, help is much appreciated!
You can get height using following code :
NSString *heightStrig = [webView stringByEvaluatingJavaScriptFromString:#"(document.height !== undefined) ? document.height : document.body.offsetHeight;"];
float height = heightStrig.floatValue;
complete code :
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
CGRect frame = webView.frame;
NSString *heightStrig = [webView stringByEvaluatingJavaScriptFromString:#"(document.height !== undefined) ? document.height : document.body.offsetHeight;"];
float height = heightStrig.floatValue + 10.0;
frame.size.height = height;
webView.frame = frame;
}
You can get the height of the content loaded into a UIWebView as follows:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
CGFloat contentHeight = webView.scrollView.contentSize.height;
}
And then adjust the frame of the web view accordingly.

Text to speech and navigation

I'm using the Acapela TTS on iOS.
I have a HTML document with all the text (and markup) that I want read out.
The text is split in paragraphs and I want to be able to start the TTS at each header.
At the moment I put each paragraph in it's own UIWebView (for handling the internal markup) and add these to a UIScrollView for navigating all the elements. Each UIWebView is overloaded with a button, so when it's pressed, the connected text is read aloud.
My problem now, is that I have to place the UIWebView and Buttons using a frame (meaning a static y-position), but this entails that I have the exact height, which is my current problem.
I have tried using the solutions mentioned in this question: UIWebView height, but it still doesn't look good - either the webviews are too high or short, and I need it to be perfect, so it looks like a consistent webpage.
Does anybody know of a different way of doing this type of TTS without splitting it up in separate webviews that I have overlooked?
This is my code that place the UIWebViews:
float yOffset = 0;
UIWebView *previous = nil;
//UIWebView delegate
-(void)webViewDidFinishLoad:(UIWebView *)webView{
NSString *height = [webView stringByEvaluatingJavaScriptFromString:#"document.body.scrollHeight;"];
if(previous!=nil){
yOffset += previous.frame.size.height;
}
CGFloat h = [height floatValue];
CGRect frame = CGRectMake(0, yOffset, scrollView.frame.size.width, h);
[webView setFrame:frame];
[webView setOpaque:NO];
[webView setBackgroundColor:[UIColor whiteColor]];
previous = webView;
[scrollView addSubview:webView];
yOffset += previous.frame.size.height;
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, yOffset)];
}
Just an idea: you could turn the complete paragraphs into clickable links that point to some identifier of the paragraph. Then you can override the clicking event with UIWebViewDelegate and get the paragraph text with javascript. I mean something like this:
HTML:
<p id="paragraph1">First paragraph</p>
<p id="paragraph2">Second paragraph</p>
Implement shouldStartLoadWithRequest of UIWebViewDelegate:
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
NSString* link = [request.URL lastPathComponent]; // not sure
// use rangeOfString to find all
if (inType == UIWebViewNavigationTypeLinkClicked && [link compare:#"paragraph1"] == NSOrderedSame)
{
// check this
NSString* javaScript =
[NSString stringWithFormat:#"document.getElementById('%#').nodeValue", link];
NSString paragraphToRead =
[webView stringByEvaluatingJavaScriptFromString:javaScript];
// read out paragraphToRead
return NO;
}
}

Resources