Detect scrolling control - ios

I have 2 ViewCollection at ViewController and function
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
}
How can I detect which collection scrolling in current function ?

UICollectionView is just a subclass of UIScrollView. Just keep reference to your collectionViews, and you can check if the scrollview and the collectionview is equal.
So simply use the following code:
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if scrollView == self.collectionViewA {
// do something with collectionViewA
} else if scrollView == self.collectionViewB {
// do something with collectionViewB
} else {
// unknown collectionView
}
}

I think this is better in Swift.
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
switch scrollView {
case collectionViewA:
// do something
case collectionViewB:
// do something
default:
break
}
}

Related

How detect which UICollectionView scrolled?

I have a multiple collectionView in one controller. One of them on top and the second on bottom. So my question is how to detect which collectionView view is scrolled?(In Objective-c) To detect scrolling i use the method: - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView . But in this method i can’t detect which collectionView is scrolled. Please help with your advice.
UICollectionView is subclass of UIScrollView so you can compare it
https://developer.apple.com/documentation/uikit/uicollectionview
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (scrollView == collectionViewOne) {
}else if (scrollView == collectionViewTwo) {
}else{
//something else
}
}
Create outlets of your collectionView.
#IBOutlet weak var topCollectionView: UICollectionView!
#IBOutlet weak var bottomCollectionView: UICollectionView!
In scrollView Delegate method:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == topCollectionView) {
}
else if (scrollView == bottomCollectionView) {
}
}
This will work as UICollectionView is subclass of UIScrollView.
In Swift You can Check Like This :
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == topCollectionViewName {
print("Call Top CollectionView")
}else if scrollView == bottomCollectionViewName{
print("Call Bottom CollectionView")
}else{
print("call any other")
}
}
In Objective C You can Check Like This :
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == topCollectionViewName) {
NSLog(#"Call Top CollectionView");
}else if (scrollView == bottomCollectionViewName) {
NSLog(#"Call Bottom CollectionView");
}else{
NSLog(#"Call any other");
}
}
Happy To Help You :)
// create outlets of both collectionview
#IBOutlet weak var collectionViewA: UICollectionView!
#IBOutlet weak var collectionVieB: UICollectionView!
// add delegate method to detect scroll of collectionview
// for swift
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if collectionView == collectionViewA{
// collectionviewA was scrolled
}else{
// collectionviewB was scrolled
}
}
// same deleagte for objc
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
// compare both collectionview here like upper swift method
}

UITableViewCell scroll detecting

I have pangesture recognizer in custom UITableViewCell and I want to disable it during table view scrolling. Is it possible to detect in custom UITableViewCell is table view is scrolling?
As #jarvis12 mentioned in comment, UITableView inherits from UIScrollView and you can take advantage of its delegate methods.
Add a global bool variable which will act as a flag to check current state of scrolling.
var isScrolling = false
Add two UIScrollView delegate methods and update isScrolling variable as below:
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
self.isScrolling = true
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
self.isScrolling = false
}
In your UITableViewCell simply add following if condition:
if isScrolling {
//disable pan gesture
}
else {
//enable pan gesture
}
Use this extension for detect specific tableview scrolling in iOS Swift
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == tableName {
// write logic for tableview disble scrolling
}
}
}

scrollViewDidEndScrollingAnimation not called

I am trying to call a method after my scroll animation is complete. I have a Table View and I set the delegate in viewDidLoad like thisself.tableView.delegate = self based on this , but that didn't help.
Basically, If a button is clicked, it scrolls up to a specific cell, lets call it the start cell, in the table view if the start cell is not visible. I'm using the scrollToRow method for the scrolling and animation
tableViewController.tableView.scrollToRow(at: IndexPath(row: techniqueNo, section: 0), at: UITableViewScrollPosition.top, animated: true)
Once this scroll animation is complete, I want to add an animation to the start cell. I tried adding this method from the scroll view delegate, but it isn't getting called
func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
print("animation Complete")
}
Any idea why this method is not getting called?
Note: This is different from UITableView is done scrolling because
(1) this is swift and that answer is Objective-C, and
(2) I have tried implementing the method from the delegate to check if the animation finished, but its not getting called and I need help figuring out why
Is this what you need?
Add these funcs to your table view controller...
Edit: forgot to include the scrollViewDidEndScrollingAnimation ...
override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
scrollingFinish()
}
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
scrollingFinish()
}
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
scrollingFinish()
}
}
func scrollingFinish() -> Void {
print("Scroll Finished!")
}

How to connect UIPageControl to UICollectionView (Swift)

I'm currently using a UICollectionView to display 3 images (each image spans the entire cell). I also have a UIPageControl that I placed on top of the UICollectionView. What I want to happen is to have the UIPageControl show the number of images (which in this case is 3), and also which image the user is currently viewing. The effect I am trying to go for is that of the Instagram app.
The way that I am currently using to achieve this effect is by placing the updating of the UIPageControl within the UICollectionView's willDisplay function, like so:
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
pictureDots.currentPage = indexPath.item
}
This manages to correctly hook up the paging effect between the collection view and page control. However, the problem that I have is that the UIPageControl starts off saying the user is on the third image, even though it is displaying the first image.
Does anyone know why this is happening and how to fix this problem?
Firstly add your UIPageControl into your storyboard with your UICollectionView, then connect them as outlets to your view controller.
#IBOutlet var pageControl: UIPageControl!
#IBOutlet var collectionView: UICollectionView!
Adjust your numberOfItemsInSection method in UICollectionViewDataSource to set the count of the page control to always be equal to the number of cells in the collection view.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let count = ...
pageControl.numberOfPages = count
pageControl.isHidden = !(count > 1)
return count
}
Lastly, using the UIScrollViewDelegate, we can tell which cell the UICollectionView stops on. If you are not using a UICollectionViewController, you may have to add the delegate protocol.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
This is possible because a UICollectionView is in fact a UIScrollView under the hood.
Step 1 Create the variables for Collection View and Page Control
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet var pageControl:UIPageControl!
Step 2 Set the number of pages of Page Control
override func viewDidLoad() {
super.viewDidLoad()
self.pageControl.numberOfPages = procedures.count
//Set the delegate
self.collectionView.delegate = self
}
*Step 3 In the scrollViewDidScroll function calculate the width of collection cell and the index for the current page.
extension YourCollectionVC: UICollectionViewDataSource, UICollectionViewDelegate {
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
let index = scrollView.contentOffset.x / witdh
let roundedIndex = round(index)
self.pageControl?.currentPage = Int(roundedIndex)
}
}
Note: This is for collection view displayed horizontally, for vertical direccion change the method.
Tested in swift 4.
Use this for smooth functioning.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
let index = scrollView.contentOffset.x / witdh
let roundedIndex = round(index)
self.pageControl.currentPage = Int(roundedIndex)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
With help of Combine, we can easily connect UIPageControl with any ScrollView.
var collectionView: UICollectionView
var bin: Set<AnyCancellable> = []
var pageControl: UIPageControl
// setup observer
collectionView
.publisher(for: \.contentOffset)
.map { [unowned self] offset in
Int(round(offset.x / max(1, self.collectionView.bounds.width)))
}
.removeDuplicates()
.assign(to: \.currentPage, on: pageControl) // may cause memory leak use sink
.store(in: &bin)
//For every iPhone screen, it is working(Swift 5)...
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
let offSet = scrollView.contentOffset.x
let width = scrollView.frame.width
let horizontalCenter = width / 2
_pageControl.currentPage = Int(offSet + horizontalCenter) / Int(width)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

Detect scrolling tableviewcell

I have a tableview that each cell contains a collectionview.How can I detect corresponding cell when user scrolls a collection?
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if (lastContentOffset.x < (scrollView.contentOffset.x)) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "scrolledRight"), object: nil)
}
}
The best way should be to create a delegate like
protocol TableCellScrollDelegate {
func didSrcoll(cell : UITableViewCell, offset : CGPoint)
}
In your TableViewCell Class, implements the UIScrollViewDelegate and then forward the message using protocol.

Resources