Disable scrollViewDidScroll: when scrolling UICollectionView - iOS - 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
}
}

Related

Detect Textview Scrolling and Tableview Scrolling

I have a TextView and a Tableview in UIView. Im trying to detect either scrolling is textview scrolling or tableview scrolling?There is any code for this? Thanks for any help in advance :)
UITableViewDelegate conforms to UIScrollViewDelegate, so all you need to implement these methods -scrollViewWillBeginDragging and -scrollViewDidScroll
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == myTableView){
// Your logic here.....
}
if (scrollView == textView)
{ // Your logic here..
}
}
UITextView & UITableView both are implemented by using UIScrollView
You can identify the which control scrolling & direction by implementing the UIScrollViewDelegate
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
if ([scrollview isKindeOfClass: [UITextView Class]]) {
//UITextView
} else if ([scrollview isKindeOfClass: [UITableView Class]]) {
// UITableView
}
// Identifying direction
CGPoint point = [scrollView.panGestureRecognizer translationInView:scrollView.superview];
if (point.y > 0) {
// Dragging down
} else {
// Dragging up
}
}
Use func scrollViewDidScroll(_ scrollView: UIScrollView) delegate and check. Set UITextViewDelegate and UITableViewDelegate and check in method
Example:
Objective-C
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if scrollView == tableView {
}
if scrollView == textView {
}
}
Swift 3.0
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == tableView {
}
if scrollView == textView {
}
}
UITableView & UITextView are a subclass of UIScrollview. So all the UIScrollView you will get when you scroll UITableView. Here you get a list of UIScrollView method.
There is UIScrollView already embedded in UITableView and UITextView
Reference
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
UITextView and UITableView are both subclasses of UIScrollView , so both of them triggers the UIScrollViewDelegate methods.
assume that __scrollView and __textView are your respective UIScrollView and UITextView,
Overriding UIScrollViewDelegate method
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ( scrollView == __scrollView ) {
// UIScrollView is scrolled
}else if ( scrollView == __textView ){
// UITextView is scrolled
}
}

iOS how to check if go to the bottom of webView

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
}
}

How can I detect the scroll direction from the UICollectionView?

I have a UICollectionView. I want to detect scroll direction. I have a two different animation style for scroll down and scroll up. So I must learn scroll direction.
CGPoint scrollVelocity = [self.collectionView.panGestureRecognizer
velocityInView:self.collectionView.superview];
if (scrollVelocity.y > 0.0f)
NSLog(#"scroll up");
else if(scrollVelocity.y < 0.0f)
NSLog(#"scroll down");
This is just work at finger touched. Not work for me
Try this:
Add this somewhere in you header:
#property (nonatomic) CGFloat lastContentOffset;
Then override the scrollViewDidScroll: method:
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (self.lastContentOffset > scrollView.contentOffset.y)
{
NSLog(#"Scrolling Up");
}
else if (self.lastContentOffset < scrollView.contentOffset.y)
{
NSLog(#"Scrolling Down");
}
self.lastContentOffset = scrollView.contentOffset.y;
}
Found in Finding the direction of scrolling in a UIScrollView?
this is the best way to get scroll direction, hope this helps you
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGPoint targetPoint = *targetContentOffset;
CGPoint currentPoint = scrollView.contentOffset;
if (targetPoint.y > currentPoint.y) {
NSLog(#"up");
}
else {
NSLog(#"down");
}
}
Swift 4.2
private var lastContentOffset: CGFloat = 0
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if lastContentOffset > scrollView.contentOffset.y && lastContentOffset < scrollView.contentSize.height - scrollView.frame.height {
// move up
print("move up")
originalHeight ()
} else if lastContentOffset < scrollView.contentOffset.y && scrollView.contentOffset.y > 0 {
// move down
print("move down")
minimizeHeaderView()
}
// update the new position acquired
lastContentOffset = scrollView.contentOffset.y
}
I was trying to find a way to detect if the user is mostly trying to pull vertically or horizontally the scrollView. I give you my solution, I hope it can be useful to anyone :
CGPoint _lastContentOffset;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_lastContentOffset = scrollView.contentOffset;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (ABS(_lastContentOffset.x - scrollView.contentOffset.x) < ABS(_lastContentOffset.y - scrollView.contentOffset.y)) {
NSLog(#"Scrolled Vertically");
} else {
NSLog(#"Scrolled Horizontally");
}
}
This work find for me and I use this to avoid the scrollView to move horizontally when scrolling vertically and opposite.

scrollViewDidEndDecelerating detect which collection view in action

I use this method to organize paging:
- scrollViewDidEndDecelerating
When I scroll my UICollectionView I change some content on my screen. But I have few UICollectionView on my screen and I need it just for one.
Well, UICollectionView inherits from UIScrollView, so you could just check which scroll view did end decelerating from within the delegate method.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (scrollView == collectionViewOne) {
}else if (scrollView == collectionViewTwo) {
}else{
//something else
}
}

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