iOS how to check if go to the bottom of webView - ios

Is there any event I can notify the supper view?
I try the scrollViewDidScroll. But it don't be called.
-(void)scrollViewDidScroll: (UIScrollView*)scrollView
{
NSLog(#"At the bottom...");
}

You must set the delegate of scrollview which in the webview to self first. So that, scrollViewDidScroll: could be call when you scroll the webview. So, try this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.webview.scrollview.delegate = self;
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollview
{
CGPoint offset = scrollView.contentOffset;
CGRect bounds = scrollView.bounds;
UIEdgeInsets inset = scrollView.contentInset;
CGFloat currentOffset = offset.y + bounds.size.height - inset.bottom;
if (currentOffset - scrollView.contentSize.height <= 0)
{
NSLog(#"At the bottom...");
}
}

If you have an instance of webView, you can get the reference of its scrollView by doing,
webView.scrollView. Set its delegate to self like so:
webView.scrollView.delegate = self;
Now, make sure you have implemented UIScrollViewDelegate in your class where you have an instance of the webView. Implement the below the code that tells you whether you have reached the bottom.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height) {
//This means that you have reached the end.
}
}

To get the call in scrollView delegate methods you need to assign the delegate for webview scroll view like this:
webview.scrollView.delegate = self;
Also Conform the UIScrollViewDelegate in .h file like this:
#interface MyController : UIViewController <UIScrollViewDelegate>
#end

If anyone is interested on how this is done in Swift 4, here it is:
Set the webviews' scrollView delegate to self in viewDidLoad() self.webView.scrollView.delegate = self
Extend your class from UIScrollViewDelegate
Implement the method scrollViewDidScroll() which will handle the scroll events
(this particular implementation is used to check if the user has scrolled to the bottom of the webview's content)
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let bottom = scrollView.contentOffset.y + scrollView.frame.size.height
if (bottom >= scrollView.contentSize.height) {
// Do something here
}
}

Related

Disable scrollViewDidScroll: when scrolling UICollectionView - iOS

I have implemented scrollViewDidScroll: inside my viewcontroller to cause some animations when I scroll the view up and down.
However, when I scroll my collectionview inside the viewcontroller (horizontally) it messes up with my animation inside scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
newAlpha = 1 - scrollView.contentOffset.y / 200;
self.introImageView.alpha = newAlpha;
//... -> prevent scrolling when collectionview is scrolled
}
How do I prevent calling scrollViewDidScroll: when scrolling my collectionview horizontally?
The best way is not to disable the delegate method, but make sure to only call that code when it's called by your scrollview. Here's an example
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.myScrollView) {
newAlpha = 1 - scrollView.contentOffset.y / 200;
self.introImageView.alpha = newAlpha;
} else {
//collectionView would fall here
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([scrollView isKindOfClass:[UICollectionView class]] == NO) {
newAlpha = 1 - scrollView.contentOffset.y / 200;
self.introImageView.alpha = newAlpha;
//... -> prevent scrolling when collectionview is scrolled
}
}

How to make UILabel position fixed?

I dragged a "Label" object into a scene in my storyboard in Xcode's Interface Builder.
The problem is that the Label is "pinned" to the top of the screen, so that when I scroll down in the View Controller, the Label is always located at the top of the screen.
What I want instead is for the Label to disappear when I scroll down and re-appear when I scroll back up. I don't want the Label to scroll at all. I want its position to be completely fixed.
I found this answer but I don't recognize the screen capture in Xcode 8.2.1.
Here is the View Controller structure:
Try this:
#interface ViewController () <UIScrollViewDelegate>
#property (nonatomic, weak) IBOutlet UILabel *fadingLabel;
#end
#implementation ViewController
#pragma mark - UIScrollViewDelegate
/* For this method to get called, make sure you set the delegate of your table view to this view controller.*/
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (!self.fadingLabel)
return;
CGFloat labelHeight = CGRectGetHeight(self.fadingLabel.frame);
CGFloat alpha = 1.0f - (scrollView.contentOffset.y / labelHeight);
[self.fadingLabel setAlpha:alpha];
}
#end
Here's the swift translation:
class ViewController: UIViewController, UIScrollViewDelegate {
private weak var fadingLabel: UILabel?
// MARK: - UIScrollViewDelegate
/* For this method to get called, make sure you set the delegate of your table view to this view controller.*/
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let label = self.fadingLabel else {
return
}
let labelHeight: CGFloat = label.frame.height
let alpha: CGFloat = 1.0 - (scrollView.contentOffset.y / labelHeight)
label.alpha = alpha
}
}
You should implement UIScrollViewDelegate and hide/show the label according to the vertical content offset of your scroll view in scrollViewDidScroll(_:).
func scrollViewDidScroll(_ scrollView: UIScrollView) {
label.isHidden = scrollView.contentOffset.y > 50
}
Don't forget to set the delegate of your scroll view:
scrollView.delegate = self

How to Stop UIWebView from “bouncing” vertically scrolling bottom?

My question is the same as this question, but has one difference. When I scroll to top refresh my website, I want stop bouncing only to the end of the bottom scroll. How do I do this?
You can try like this :
override func viewDidLoad() {
super.viewDidLoad()
webview.scrollView.delegate = self
}
func scrollViewDidScroll(scrollView: UIScrollView) {
if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height) {
scrollView.setContentOffset(CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height), animated: false)
}
}
Set the delegate of your webview and set the content offset of the webview's scrollview
Ref taken from: https://stackoverflow.com/a/14084747/4557505
Personally in Xcode 7.3 in Swift, I Simply add this in the viewDidLoad Function:
UIWebview.scrollView.bounces = false;
I think you can also set the scrollview's bounces
like this,It's simple
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.contentOffset.y > 0) {
scrollView.bounces = NO;
}else{
scrollView.bounces = YES;
}
}

Scrolling one UIScrollView Proportionately to Another

I have two UIScrollViews with vertical scroll: foreground and background. The user can only interact with the former; the latter is moved programmatically. How can I make it so that when the user scrolls the foreground, the background scrolls at a proportional rate of ¼? For example, for every 4px that foreground scrolls, background will scroll 1px in the same direction.
How can I achieve this relationship in Swift2?
set your self as the scrollView delegate -
self.foregroundScrollView.delegate = self
and use the UIScrollViewDelegate methods:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.lastY = scrollView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Calculate how much distance the scrollView has travelled since last scroll
CGFloat currentY = scrollView.contentOffset.y;
CGFloat difference = currentY - self.lastY;
// Set new contentOffset for your background scrollView
CGPoint currentBackgroundOffset = self.backgroundScrollView.contentOffset;
currentBackgroundOffset.y += difference/4;
self.backgroundScrollView.contentOffset = currentBackgroundOffset;
// Don't forget to update the lastY
self.lastY = currentY;
}
Swift:
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
lastY = scrollView.contentOffset.y
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// Calculate how much distance the scrollView has travelled since last scroll
let currentY = scrollView.contentOffset.y
let difference = currentY - lastY
// Set new contentOffset for your background scrollView
var currentBackgroundOffset = backgroundScrollView.contentOffset
currentBackgroundOffset.y += difference/4
backgroundScrollView.contentOffset = currentBackgroundOffset
// Don't forget to update the lastY
lastY = currentY
}

Detect UITextView scroll location

I am trying to implement a form of a Terms & Conditions page where the "Proceed" button is only enabled once the user has scrolled to the bottom of a UITextView. So far I have set my class as a UIScrollView delegate & have implemented the method below:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(#"Checking if at bottom of UITextView");
CGPoint bottomOffset = CGPointMake(0,self.warningTextView.frame.size.height);
//if ([[self.warningTextView contentOffset] isEqualTO:bottomOffset])
{
}
}
I have commented the if statement because I am not sure how to check if the UITextView is at the bottom.
UITextView is a UIScrollView subclass. Therefore the UIScrollView delegate method you are using is also available when using UITextView.
Instead of using scrollViewDidEndDecelerating, you should use scrollViewDidScroll, as the scrollview may stop scrolling without deceleration.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height)
{
NSLog(#"at bottom");
}
}
A Swift version for this question:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height {
print( "View scrolled to the bottom" )
}
}
This should solve it. It works. I am using it.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height)
{
// we are at the end
}
}

Resources