Detect Textview Scrolling and Tableview Scrolling - ios

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

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 scroll two UITableViews symmetrically?

In my app I have two table views. Both are same height and width and same cell count.
I want when tableview A Scroll Simultaneously tableview B also scroll.
You can use scrollview delegate scrollViewDidScroll for this purpose. This will do the exact thing you want.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.tableA{
self.tableB.setContentOffset(self.tableA.contentOffset, animated: false)
}
else if scrollView == self.tableB{
self.tableA.setContentOffset(self.tableA.contentOffset, animated: false)
}
print("scrollViewDidScroll") // to check whether this function is called while scrolling
}
TRY THIS:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
<your tableView Name>.contentOffset = scrollview.contentOffset
}
As Tableview inherits from ScrollView. Try this.
FOR SWIFT 4:
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
<your tableView Name>.contentOffset = scrollview.contentOffset
}
Instead of using tableview you can use UIPickerView with two components.
If you need code let me know.

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

UICollectionView: how to detect when scrolling has stopped

I'm using a UICollectionView to scroll through a set of thumbnails quickly. Once scrolling ends, I'd like to display a larger hi-res version of the current thumbnail.
How can I detect when the user has completed scrolling? I do implement didEndDisplayingCell, but that only tells me when a particular cell has scrolled off; it doesn't tell me when the scroll motion actually completes.
NS_CLASS_AVAILABLE_IOS(6_0) #interface UICollectionView : UIScrollView
UICollectionView is a subclass of UIScrollView. So if you have set the delegate and implemented UIScrollViewDelegate, you should be able to detect this the same way as UIScrollView.
For eg:-
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
As per documentation, the above method should tell when the scroll view has ended decelerating the scrolling movement.
Just to cover your bases you should implement both these UIScrollViewDelegate methods.
In some cases there may not be a deceleration (and scrollViewDidEndDecelerating would not be called), for e.g., the page is fully scrolled in place. In those case do your update right there in scrollViewDidEndDragging.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self updateStuff];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self updateStuff];
}
An important fact to note here.
This method gets called on User initiated scrolls (i.e a Pan gesture):
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
or in Swift:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
On the other hand, this one gets called on all manually (programatically) initiated scrolls (like scrollRectToVisible or scrollToItemAtIndexPath):
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
or in Swift:
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
Swift 3 version of Abey M and D6mi 's answers:
When scroll is caused by user action
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if (!decelerate) {
//cause by user
print("SCROLL scrollViewDidEndDragging")
}
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
//caused by user
print("SCROLL scrollViewDidEndDecelerating")
}
When scroll is caused by code action (programmatically): (like "scrollRectToVisible" or "scrollToItemAtIndexPath")
public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
//caused by code
print("SCROLL scrollViewDidEndScrollingAnimation")
}
Notes:
Put these functions in your UIScrollViewDelegate or UICollectionViewDelegate delegate.
if you don't have a separate delegate, make your current class extend a UIScrollViewDelegate op top of your class file
.
open class MyClass: NSObject , UICollectionViewDelegate
and somewhere in your viewWillAppear make the class its own delegate
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// ...
self.myScrollView.delegate = self
// ...
}
Swift 3 version:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Your code here
}
if you want to use the visible indexpath:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self scrollingFinish];
}
- (void)scrollingFinish {
if([self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader]){
NSIndexPath *firstVisibleIndexPath = [[self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader] firstObject];
[self.collectionView scrollToItemAtIndexPath:firstVisibleIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
}
Get your collection view index and Dont forget to import UISCrollViewDelegate in your class
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let xPoint = scrollView.contentOffset.x + scrollView.frame.width / 2
let yPoint = scrollView.frame.height / 2
let center = CGPoint(x: xPoint, y: yPoint)
if let ip = self.collectionView.indexPathForItem(at: center) {
pageIndex = ip.row
}
print(">>>>>>>>>\(pageIndex)")
}

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