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!")
}
Related
I am using a UIViewController which contains a ContainerView. Inside the ContainerView I have a UITableViewController. I have a PanGestureRecognizer in my UIViewController which I use for dismissing it. Now the problem I have is that when I pan to close the UIViewController, the TableViewCells inside UITableViewController that are touched become briefly highlighted.
I have disabled scrolling in my tableview as I don't need it.
I added this to my pan gesture handler's .began but it didn't have any effect:
myTableView.isUserInteractionEnabled = false
I also tried:
myGestureRecognizer.cancelsTouchesInView = true
but the touches are still passed to the TableView and cause the cells to become highlighted. Is there any solution for this?
I ended up using this:
myGestureRecognizer.delaysTouchesBegan = true
It may not be useful in every situation, but for my TableView it prevents the highlights from happening.
You could try immediately deselecting rows that are selected in the delegate method for didSelectRow.
extension MyViewController: UITableViewDelegate {
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
Will prevent cells from being highlighted when selected. From my experience, this is somewhat common practice.
EDIT: My mistake, misread the question. In which case, you could consider using the tableView's scrollView delegate to determine when you're scrolling, and disable interaction on the individual cells like so:
class ViewController: UIViewController {
private var areCellsDisabled = false {
didSet {
tableView.reloadData()
}
}
// Rest of your view controller logic here...
}
extension ViewController: UITableViewDelegate {
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
areCellsDisabled = true
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
areCellsDisabled = false
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Configure/dequeue the cell, etc.
if areCellsDisabled {
cell.isUserInteractionEnabled = false
} else {
cell.isUserInteractionEnabled = true
}
return cell
}
}
This might be taking a hammer to the problem, though. Let me know if it helps.
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
}
}
}
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.
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
}
}
This question already has an answer here:
In UITableView, what's the delegate for "visibleCells"?
(1 answer)
Closed 7 years ago.
As the user scrolls down the tableView, the cells are being dequeued and queued.
I'd like to know, inside my UITableViewCell, when this happens.
If it's not possible, could we use notification centers to achieve this (using the delegates of the table view?)
Note: I want the cell itself to know when it's being dequeued.
I know that there is already 2 delegates from UITableView I can use, but I rather not use those.
I had similar task and I came to using this methods:
override func willMoveToSuperview(_ newSuperview: UIView?)
{
super.willMoveToSuperview(newSuperview)
if newSuperview != nil
{
// Cell will be added to collection view
}
else
{
// Cell will be removed
}
}
override func didMoveToSuperview()
{
// You can also override this method, check self.superview
}
As I remember these methods worked much more stable than prepareForReuse(). But the delegate methods are more robust anyway.
When a cell is no longer needed, it's removed from the UITableView, in order to detect when this happens you can override the removeFromSuperView method. However when you're scrolling, cells get reused, so you also need to do the same cleanup in prepareForReuse.
As for detecting when it was added to the table view, you can add a configure method that gets called by cellForRowAtIndexPath:, as most likely you anyhow need to implement cellForRowAtIndexPath:.
class MyTableViewCell: UITableViewCell {
func configure(obj: MyDataObject) {
// intialize whathever you need
}
func doCleanup() {
// cleanup the stuff you need
}
override func removeFromSuperview() {
super.removeFromSuperview()
doCleanup()
}
override func prepareForReuse() {
super.prepareForReuse()
doCleanup()
}
}