My app has a UIWebView that displays HTML emails. If I zoom in on the content and then double-tap on it a couple of times, the email content eventually gets resized so that it all fits on the screen again.
I'd like to programmatically reproduce this resizing behavior (I want to be able to call a function that re-scales the content so that it all fits on the screen); calling sizeToFit on the web view does not seem to have any effect.
If you know the CGRect you want to scale it to, then you can use,
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
As UIWebView is scrollable, So I guess you should be able to do this.
Apparently your UIWebView should have an iVar named scrollView. So, if your UIWebView object name is webView. just do something like, below code might not be 100% syntactically correct. But you must have got the idea.
[webView.scrollView zoomToRect:CGMakeRect(0,0,0,0) animated:YES];
Related
I've been researching how to use a UIWebView embedded in a UIScrollView for a while now and cant seem to find an easy fix to my problem. I'm using a UIWebView because a UITextView, although allowing hyperlinks, does not allow you to change the link color from the standard blue apple sets.
But using a UIWebView introduces another problem: It blocks the UIScrollView it is embedded in from handling scroll events because a UIWebView handles these events within its own private implementation.
Although this allows me to use its embedded links, the UIWebView absorbs the touch events which doesn't allow me to scroll up/down when dragging within the UIWebView itself. I worked around this problem by placing a transparent UIView overlay exactly over the UIWebView, intercepting the touch events that it receives, and resigning it as first responder so that the UIScrollView that they are both subviews of can handle the scrolling appropriately.
Now, however, I can't seem to think of solution to the new problem this introduces: I can't click on the links within my UIWebView that is right under the UIView Overlay.
What is the best way to forward touch events to a UIWebView that is right underneath my transparent UIView in order to trigger my UIWebView's delegate method 'webView:shouldStartLoadWithRequest:navigationType:' for tapping on links?
FYI from UIWebView API doc:
Important: You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.
Back to the question,
UIWebView has property called scrollView, try doing:
webView.scrollView.scrollEnable = NO;
I want to make the scrollRectToVisible:animated: work even when the contentSize is only set to 1 page size.
The reason: I have multiple pages in the UIScrollView but want to maintain the hard-drag provided by the UIScrollView when it is on the edges. If I set the contentSize accordingly to the number of pages I actually have, that hard-drag will be lost.
How I wish it worked:
I keep track of which page to go to in "- (void)scrollViewDidScroll:(UIScrollView*)scrollView"
I then call "[self.scrollView scrollRectToVisible:frame animated:YES];" in "- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate" if the next page number is different than the current one.
What happens: Nothing, the scrollRectToVisible:frame animated:YES does nothing because the contentSize is set to only 1 page width&height. I have tried to set the contentSize to be 2*height before calling the scrollRectToVisible method, and it sort of works, but scrolls back to the current page number.
So my question is, how can I force the UIScrollView to scroll to a certain position or at least emulate that behaviour?
I've solved the issue using another method. I keep track of the position in "scrollViewDidScroll" and animate all the UIViews position accordingly. If anyone wants more information about this let me know, but I think it's pretty straight forward and way more simple than what I was trying to achieve before.
I have a paging scrollview much like Apple's Page Control example project which I have adapted into a horizontal picker. I would really like the ability to scroll through many pages per flick gesture instead of one-at-a-time, much like how UIPickerViews work. Looking for some guidance on how to approach this. Thanks!
First here best Source Code
It could be that whatever is setting those numbers in there, is not greatly impressed by you setting the contentOffset under its hands. So it just goes on setting what it thinks should be the contentOffset for the next instant - without verifying if the contentOffset has changed in the meantime.
I would subclass UIScrollView and put the magic in the setContentOffset method. In my experience all content-offset changing passes through that method, even the content-offset changing induced by the internal scrolling. Just do [super setContentOffset:..] at some point to pass the message on to the real UIScrollView.
Maybe if you put your shifting action in there it will work better. You could at least detect the 3000-off setting of contentOffset, and fix it before passing the message on. If you would also override the contentOffset method, you could try and see if you can make a virtual infinite content size, and reduce that to real proportions "under the hood".
This is also helpful for you..!!!
I'm trying to create an app that will have an interface similar to the Mail app on the iPhone. When you view an email message on the built-in Mail app, it displays sender/receiver information in addition to the subject in an area before the message. I was thinking of using a WebView for the message portion, but I can't figure out a way to have some custom view appear above the WebView while still within the same ScrollView.
What is the best way to implement this? To me the best option seems to be generating the "custom view" at the top in HTML/CSS, and simply appending the message's HTML afterward. I've looked at trying to put a WebView with another view inside a ScrollView, but it seems to go against Apple's design guidelines.
Any ideas or suggestions would be great.
Thanks,
Thomas
I don't hink it is against Apple guidelines.
What I'd do in your case is the following.
First create the scroll view
Place inside it your fixed height header (with subject, etc...)
Then place inside the scrollview a webView with an y offset of your headers height.
After the webView is done loading call [webView sizeToFit]; (wich resizes the view trying not to crop subViews)
Maybe you'll have to set the y offset again (frame.origin.y=offset)
And then set the scrollview content size to the sum of the two heights:
scrollView.contentSize=CGSizeMake(width, headerView.frame.size.height + webview.frame.size.height);
I'm not really confident with what [webView sizeToFit] is going to do. I've read you can also use [webView sizeThatFits:CGSizeZero]; . It will apparently return the needed size for the webView.
The you would simply have to change the webviews frame size to the return value of that function and use the same contentsize statement as before.
Hope this helped
PS: I think it's a bad idea to use html as a replacement for views. It's much slower and it takes initial time to load. The only use I've found to it is for displaying formatted text.
In my custom UIViewController I have two distinct UIWebViews for which my custom UIViewController is the delegate. In webViewDidFinishLoad:webView I call [webView sizeToFit] and I can confirm it gets called twice, one for each UIWebView. However, to my great dismay, it only seems to affect the first one that gets called, while the other one remains unchanged. Obviously both their contents exceed the bounds, so I expect them to be resized accordingly.
Now, after lots of hours spent on this issue, how am I even supposed to proceed to understand what's wrong?
EDIT: Alright, apparently the problem is that the view in which I put the second UIWebView is not visible on the screen when I call sizeToFit. Calling it with a delay after the view is shown results in the expected behaviour. Now I have to find a way to do this without showing it, because I need to to be visible at a later time. Ideas?
It seems that doing that on viewDidAppear works like a charm.