Objective-C: Set UIWebView's ScrollView - ios

I am trying to set the webview's scrollview using the code below but it disabled the scrolling/interaction of the webview.
[webView sizeToFit];
webView.scrollView.scrollEnabled = YES;
webView.scrollView.contentSize = CGSizeMake(375, rfqWeb.scrollView.contentSize.height + 700);
rfqWeb.userInteractionEnabled = YES;

If you want to change the "scrollable size", I suggest to do:
- (void)setInsetsTop:(CGFloat)top bottom:(CGFloat)bottom {
self.webview.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, self.view.frame.size.height - bottom);
[[self.webview scrollView] setContentInset:UIEdgeInsetsMake(top, 0, bottom, 0)];
}
I call it from another class
[htmlWebViewController setInsetsTop:0.0f bottom:44.0f];
If you use it in the same class just use
[self setInsetsTop:0.0f bottom:44.0f];

Related

How to disable the animation scrolling in a UIScrollView in Objective C?

I loaded a pdf in a scrollview, and I would like to go directly to the next page without having the animation scrolling.
CGRect scrollViewRect = CGRectInset(viewRect, -scrollViewOutset, 0.0f);
theScrollView = [[UIScrollView alloc] initWithFrame:scrollViewRect]; // All
theScrollView.autoresizesSubviews = NO;
theScrollView.contentMode = UIViewContentModeRedraw;
theScrollView.showsHorizontalScrollIndicator = NO;
theScrollView.showsVerticalScrollIndicator = NO;
theScrollView.scrollsToTop = NO;
theScrollView.delaysContentTouches = NO;
theScrollView.pagingEnabled = YES;
theScrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
theScrollView.backgroundColor = [UIColor clearColor];
theScrollView.delegate = self;
[self.view addSubview:theScrollView];
Is it possible ?
You have to use below method to jump on direct offset of your next page by below method.
[objUIScrollView setContentOffset:CGPointMake(YOUR_X, YOUR_Y) animated:NO]
animated = NO;
If you are loading PDF through WebView than you need to follow below code:
webview.scrollView.contentOffset = CGPointMake(YOUR_X, YOUR_Y);
Note : Use this above code in your Next Button page or after loading
WebView properly may be in below method.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
Hope this will work as you expected.
Sure, simply use:
[theScrollView scrollRectToVisible:CGRectMake(0.0f, 0.0f, 0.0f, 0.0f) animated:NO];
or
[theScrollView setContentOffset:CGPointMake(0.0f, 0.0f) animated:NO];
and change the CGPoint or CGRect to the offset of the page of your liking.

UIScrollView view port coordinates

This is how I am adding UIScrollView in my viewDidLoad
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
scrollView.backgroundColor = [UIColor redColor];
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width , self.view.bounds.size.height * 2);
[self.view addSubview:scrollView];
scrollView.delegate = self;
When the scrollView is loaded for the first time it's coordinates are : {(0,0), (widthOfiPhone, 0), (0, heightOfiPhone), (widthOfiPhone, heightOfiPhone)}
Whenever the scroll finishes, I want to get the co-ordinates of viewport in scrollview. How to do this? Thanks
Edit:
Image Credits: https://oleb.net/blog/2014/04/understanding-uiscrollview/
First, observe scrollview agent, and then implement its proxy method
(void) scrollViewDidEndDecelerating: (UIScrollView *) scrollView {
NSLog (# "% f,% f,% f,% f", scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height);
}
This should be possible
You can implement UIScrollView delegate method to detect when scroll is end : scrollViewDidEndDecelerating and in this method you can get coordinates of your scrollview and it's content. Btw content's cooridinate will be same with respect scrollview!!!
You can get visible rect from scrollview like,
CGRect visibleRect = [subViewOfScrollView convertRect:subViewOfScrollView.bounds toView:self.view];

Adding header view to WKWebView ScrollView

Has anyone managed to successfully add a header or footer view to a WKWebView ScrollView?
I'm currently trying to do this using the method described here for a UIWebView Adding a header view to a UIWebView similar to Safari and Articles.
When this method is used in a WKWebView the content view origin.y is correctly changed but content is cut off at the bottom.
Using the scroll view content offset is also not possible as it breaks fixed positioned CSS elements in the web view.
In webView Delegate method
- (void)webViewDidFinishLoad:(UIWebView *)webView
add the following codebase,
mainWebViewObj.scrollView.contentInset = UIEdgeInsetsMake(headerView.frame.size.height,0.0,headerView.frame.size.height,0.0);
mainWebViewObj.scrollView.backgroundColor = [UIColor whiteColor];
if(![headerView superview])
{
[webView.scrollView addSubview:headerView];
[webView.scrollView bringSubviewToFront:headerView];
}
[mainWebViewObj.scrollView setContentOffset:
CGPointMake(0, -mainWebViewObj.scrollView.contentInset.top) animated:NO];
this worked perfect for me. Hope it solves your problem.
Here's an example that I think does as you describe. It offsets the web content by setting contentInset on the scrollView, and by offsetting the header view frame by a negative amount:
#implementation ViewController
{
WKWebView* _webView;
UIView* _headerView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_webView = [[WKWebView alloc] initWithFrame: self.view.bounds];
[self.view addSubview: _webView];
[_webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: #"http://www.stackoverflow.com"]]];
[_webView.scrollView setContentInset: UIEdgeInsetsMake(100, 0, 0, 0)];
_headerView = [[UIView alloc] initWithFrame: CGRectMake(0, -100, 375, 100)];
_headerView.backgroundColor = [UIColor redColor];
[_webView.scrollView addSubview: _headerView];
}
- (void) viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
_webView.frame = self.view.bounds;
CGRect f = _headerView.frame;
f.size.width = _webView.bounds.size.width;
_headerView.frame = f;
}

UIScrollView paging enabled with content inset is working strange

I created the UIScrollView with content insets.
scrollView.frame = CGRectMake(-80, 180, 480, 190)
self.scrollView.contentInset = UIEdgeInsetsMake(0, 160, 0, 160);
self.scrollView.pagingEnabled = YES;
[self.scrollView setContentSize:CGSizeMake(480, 190)];
// Add three Views
[self.scrollView addSubview:view1];
[self.scrollView addSubview:view2];
[self.scrollView addSubview:view3];
[view1 setFrame:CGRectMake(0, 0, 160, 190)];
[view2 setFrame:CGRectMake(160, 0, 160, 190)];
[view3 setFrame:CGRectMake(320, 0, 160, 190)];
At first time, scrollView.contentOffset.x was -160.0
But the weird problem is when I tap on scrollView(Yellow Area), content offset x value is resetting to 0 and shown like this.
I tried several times, but tapping on Scroll View resets the content offset to 0.
How can I prevent this?
UIScrollView paging works by scrolling pages with the same width of the scrollView (in your case pages of 480 width). This means that you have 1 single page (you'd still be able to scroll left and right due to the 160 content inset).
One way to make this work would be:
self.scrollView.frame = CGRectMake(80, 180, 160, 190);
self.scrollView.clipsToBounds = NO;
self.scrollView.contentInset = UIEdgeInsetsZero;
self.scrollView.pagingEnabled = YES;
[self.scrollView setContentSize:CGSizeMake(480, 190)];
This will draw and scroll correctly, however, the sides of the screen will not be interactive (80 pixels on each side, since the control starts at frame.origin.x=80 and ends at 80+160=240).
Second option would be to handle paging yourself, by using methods provided by UIScrollViewDelegate.
- (void)viewDidLoad
{
[super viewDidLoad];
// pageIndex must be declared as a class member - this is used to prevent skipping pages during scroll
pageIndex = 0;
self.scrollView.frame = CGRectMake(0, 180, 320, 190);
self.scrollView.contentInset = UIEdgeInsetsMake(0, 80, 0, 80);
self.scrollView.pagingEnabled = NO;
self.scrollView.clipsToBounds = YES;
[self.scrollView setContentSize:CGSizeMake(480, 190)];
self.scrollView.delegate = self;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
int pageWidth = 160;
int pageX = pageIndex*pageWidth-scrollView.contentInset.left;
if (targetContentOffset->x<pageX) {
if (pageIndex>0) {
pageIndex--;
}
}
else if(targetContentOffset->x>pageX){
if (pageIndex<3) {
pageIndex++;
}
}
targetContentOffset->x = pageIndex*pageWidth-scrollView.contentInset.left;
NSLog(#"%d %d", pageIndex, (int)targetContentOffset->x);
}
In addition to alex's first approach with setting clipsToBounds to NO, I need to react to the scroll outside of the scroll view bounds. So I created ScrollForwarderView class which is subclass of UIView.
ScrollForwarderView.h
#import <UIKit/UIKit.h>
#interface ScrollForwarderView : UIView
#property (nonatomic, weak) UIScrollView *scrollView;
#end
ScrollForwarderView.m
...
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if ([self pointInside:point withEvent:event]) {
return _scrollView;
}
return nil;
}
Then place UIView with custom class ScrollForwarderView above the scroll view, link scrollView property to my scroll view and it nicely forwarded the user events to scrollview.

UIWebView scrollView.contentSize.height not changed

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.

Resources