How to get rid of adjustedContentInset in UIWebview? - ios

I have a UIWebView in which i load content from remote URL. Problem i am facing is, last part of the content of webview is not scrollable. When debugging i noticed that adjustedContentInset is set as {0, 0, 49, 0}. Perhaps that is the reason partial webview content(49 pts from end) is not scrollable. Is there any way i can get rid of adjustedContentInset so that the whole content becomes scrollable?
I tried setting the contentInsets of webview's scrollview to {0,0,0,0} but it didn't help.
UITableView and UICollectionView has contentInsetAdjustmentBehavior method to reset adjustedContentInset but i couldn't find such property for UIWebView.
Any help will be appreciated.

Actually, contentInsetAdjustmentBehavior is a UIScrollView property, that's why what you mentioned:
UITableView and UICollectionView has contentInsetAdjustmentBehavior
method to reset adjustedContentInset but i couldn't find such property
for UIWebView.
is correct.
That means contentInsetAdjustmentBehavior is not a property for the UIWebView (UIView), what would you need to do is to access it via the web view scrollView property:
The scroll view associated with the web view.
Discussion
Your app can access the scroll view if it wants to customize the
scrolling behavior of the web view.
which exactly what are you aiming to. Therefore:
webView.scrollView.contentInsetAdjustmentBehavior = ...
should work.

Related

Passing an existing UIWebView to another view for usage?

I have a bunch of UIWebViews in the cells of a UITableView. When tapped, I'm opening up a new view and recreating the UIWebView in the cell.
Obviously it would be greatly advantageous if I could use the webView instance that already exists, saving the user from opening the web page twice.
However, when I tried passing the webView and adding to its new parent UIView object, the webview seems to have issues resizing itself. Its simply not adjusting its height and width, even though I explicitly adjust it and confirm the new frame size. Is it not possible to resize a webview's frame? Or am I missing something?
Thanks
I'm almost positive this is possible. I've done it with custom videoPlayerViews, passed them from a collectionViewCell to a viewController.
Some ideas:
Make sure that you remove the webView from its original superview before adding it as a subview of its new superview.
Make sure your autoResizingMask and constraints are set up properly with respect to the new superview, and destroyed with respect to the original superview.

UITableView + UIWebView within UIScrollView

I'm struggling with wrapping my head around using UITableView with UIWebView within UIScrollView. The interface I'm trying to build consist of a header (containing a few labels, always the same size), UIWebView (can be any height, I'm scaling it dependently on the content) and a UITableView (also can have any number of elements). I want user to scroll through the whole content like he would be scrolling through one page.
I realize that Apple doesn't recommend using UITableView or UIWebView within UIScrollView. However, I'm having a hard time to think about some workaround.
Is it possible to get the desired effect done the way I'm trying to do it right now? If not, what would be the cleanest or at least working way of doing it?
(I'm currently using Xcode 6 beta 3 / swift)
You can set your UIScrollView's contentSize.height to the sum of your UITableView's contentSize.height and the height of your UIWebView's content.
To get it, just add this to your ViewController after setting it as your UIWebView's delegate:
func webViewDidFinishLoad(webView: UIWebView!) {
let output = webView.stringByEvaluatingJavaScriptFromString("document.body.offsetHeight;")
let contentHeight = (output as NSString).floatValue
}
Then, you just have to set the frame height of your tableView and webView to their content's height and place them correctly in the scroll view.
Hope this will help,

Partial black background in UIWebView on iOS7 after setting content inset

I have a problem with UIWebView on iOS7:
First I'm setting the content inset for my web view scrollview:
[webView.scrollView setContentInset:UIEdgeInsetsMake(40, 0, 0, 0)];
Then when web view loads an empty page there is a black rectangle at the bottom of the web view, that has the height 40.
It's for sure because of content inset, and I met this problem only on iOS7. How can I solve this? Any help will be appreciated!
Try this code, it is not the best solution, but it will get rid the black rectangle:
[webView.scrollView setContentInset:UIEdgeInsetsMake(40, 0, -40, 0)];
From my experience, iOS7 UIWebView does not play nice at all with custom insets and content size. It always breaks under certain conditions. We use a webview for a rich text editor, so we had to manage a volatile contentEditable="true" webview.
What we ended up doing was to take the UIWebDocumentView/UIWebBrowserView (let's call it "internal view") from the UIWebScrollView and add it as a subview in a scrollview of our own. To do this safely, we iterate the subviews of webView.scrollView and took the one whose class name has a UIWeb prefix. (You have to remember that iOS6 UIWebScrollView contains shadows as well.)
Now you have to manage your scrollview. What we did was observe changes of the frame property of the internal view and update the scrollview's contentsize accordingly.

Showing scroll indicators on a UIScrollView when programmatically scrolling

EDIT: The crux of this problem is that scroll indicators do not show during programmatic scrolling, but I would like them to. My original question (provided below) assumed this had something to do with userInteractionEnabled, but it does not. The mention of a master and slave UIScrollView is also possibly distracting from my core problem (the need to show scroll indicators during a programmatic scroll). Apologies to those of you who answered or commented based on my misleading assumptions/info.
Possible Solution: The only way I found to do this was to use the fact that scroll indicators are instances of UIImageView and use a category on it to hack the alpha. This article shows the approach. It was then a case of using tags and scroll view delegate methods to turn the alpha permanently on prior to a programmatic scroll, and permanently off when the scroll is finished. This feels hacky though, so any further suggestions would be welcome!
Everything below this line is the original unedited question to provide context to users' answers and comments
Setting userInteractionEnabled in a UIScrollView object to NO appears to disable the scroll indicators upon programmatic scrolling. This happens even if you have self.showsVerticalScrollIndicator = self.showsHorizontalScrollIndicator = YES;
Is there any way to programmatically scroll the scroll view but still show the indicators?
(To provide some context: I have a slave scrollview that mimics a master scrollview by hooking up the scrollview delegate callbacks and passing the content offset to the slave scrollview. However, I don't want the user to be able to directly manipulate the slave scrollview, but I do want scroll indicators).
Instead of setting userInteractionEnabled to false try setting the UIScrollView's scrollEnabled property to false. The doc. says "When scrolling is disabled, the scroll view does not accept touch events" that should mean that you should still be able to programmatically scroll the UIScrollView. Hope this helps - Did not test it out let me know.
You could try putting a transparent UIView (alpha == 0.0) over your scroll view (but as a sibling in the view hierarchy, not as a subview). Set touchesEnabled to YES on the transparent view, and it will intercept touches heading for the scroll view.

how to forward UIWebView scroll to UIScrollView ? (conditionally)

I have a UIWebView inside UIScrollView.
This idea is to be able to create more reading space on screen when user scroll the webpage upwards - by scrolling the UIScrollView upwards till the toolbar is visible, and obviously when the toolbars is nomore visible actually scroll the webpage to show more content that's on the page.
IPhone Safari browser does exactly the same functionality.
see screenshot (first) for default behavior i am getting - i guess because : the scrolling message is consumed by the webview since the touch/scroll is happening directly on webview area.
what i would like to do here is programatiicaly decide when to forward the 'upward scroll' to the UIScrollivew and when not to.
Any tips on how to get around this will be so helpful. Thanks!!
The UIWebView class reference discourages embedding a UIWebView in a UIScrollView:
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.
However I suppose you still want to implement your feature ;-)
Idea 1: Don't embed the UIWebView in a UIScrollView, instead run javascript using UIWebView's stringByEvaluatingJavaScriptFromString: method, modifying the DOM to add a toolbar below. If required, you can callback objective-c code from any buttons pushed on the toolbar by registering some custom URL schemes.
Idea 2: Don't embed the UIWebView in a UIScrollView, but in a normal UIView. Building on Vignesh's suggestion, listen for your webView's inner scrollView's scrollViewDidScroll: callback via the delegate, checking the contentOffset vs. the contentSize's height each time the callback is called. Once they are equal, it means you got to the bottom. Once this happens you can animate your toolbar's frame to "enter" the containing UIView and "push" the webView's frame away.
Idea 3: Ignore Apple's recommendation, and embed the UIWebView in a UIScrollView. Building on Vignesh's suggestion, listen for your webView's inner scrollView's scrollViewDidScroll: callback via the delegate, checking the contentOffset vs. the contentSize's height each time the callback is called. Once they are equal, it means you got to the bottom. Once this happens set the userInteractionEnabled property of the webView to NO, and set it to YES on the scrollView which contains the webView and the toolbar. Hopefully the scroll will continue smoothly enough. Of course you have to listen to the containing scroll view in the same way to determine when to switch back the userInteractionEnabled.
A variation on this idea would be to just set userInteractionEnabled to NO for the webView, but set the webView's frame's height to match its contentSize, and also enlarge the contentSize of the containing scrollView accordingly.
Both variations have the drawback that in some cases you won't be able to do things such as click on links :-( But maybe that's good enough for your case. At least in the first variation it's not so bad.
You can add a searchbox and uiwebview in a UIscrollview one below another. To get the content offset when webview is scrolled you can use the following code snippet.
UIScrollView* currentScrollView;
for (UIView* subView in testWebView.subviews) {
if ([subView isKindOfClass:[UIScrollView class]]) {
currentScrollView = (UIScrollView*)subView;
currentScrollView.delegate = (id)self;
}
}
Now you can change your base scrollview offset's y value to the offset value you get from the scrollview didscroll delegate method.
Advanced ScrollView Techniques
https://developer.apple.com/videos/wwdc/2011/

Resources