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
}
}
}
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.
So I have a UIViewController that have a collectionView with horizontal scrolling (like the facebook stories on the top of newsFeed page) and under it is the tableView with cells. How can I hide this collection view when I scroll down the tableView? I want it to exactly like facebook.
You have to set collectionView height constraint, and when you begin dragging table view:
heightConstraint.constant = 0
You can know about start dragging from table view delegate. For this you should inherit your viewController from UITableViewDelegate and set a function :
class ViewController: UIViewController, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("begin dragging")
heightConstraint.constant = 0
}
}
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!")
}
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
}
}