Cards icon indicating copy to clipboard operation
Cards copied to clipboard

Dismiss detail view controller by scrolling on content

Open arinasawa opened this issue 5 years ago • 4 comments

Is there a way to dismiss the detail view controller only by performing a gesture on the image view rather than the whole content of the detail view controller?

arinasawa avatar Apr 01 '19 06:04 arinasawa

Actually, I don't think so. You can try preventing user interaction in the scroll view of DetailViewController file, and then call dismiss() on backroungIV view pan gesture. Let me know if you're having troubles ;)

PaoloCuscela avatar Apr 01 '19 08:04 PaoloCuscela

I can’t seem to figure out how to do what you said above? Do you have any example code that can achieve this?

arinasawa avatar Apr 02 '19 14:04 arinasawa

Forgive me if I have expressed myself badly, english isn't my first language. Anyway, the detail view controller's view is composed of a scrollview that contains the card content on top and the view managed by a 3rd ViewController below. So actually there isn't a way to do what you asked for, but you can try to achieve this by playing with the scroll view Delegate methods:

// Line 176 //MARK: - ScrollView Behaviour
extension DetailViewController: UIScrollViewDelegate {
    
  public func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
        let y = scrollView.contentOffset.y
        let offset = scrollView.frame.origin.y - scrollViewOriginalYPosition
        
        // Behavior when scroll view is pulled down
        if (y<0) {
            scrollView.frame.origin.y -= y/2
            scrollView.contentOffset.y = 0
        
          // Behavior when scroll view is pulled down and then up
        } else if ( offset > 0) {
          
            scrollView.contentOffset.y = 0
            scrollView.frame.origin.y -= y/2
        }
        
        card.delegate?.cardDetailIsScrolling?(card: card)
    }
    
    public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        
        let offset = scrollView.frame.origin.y - scrollViewOriginalYPosition
        
        // Pull down speed calculations
        let max = 4.0
        let min = 2.0
        var speed = Double(-velocity.y)
        if speed > max { speed = max }
        if speed < min { speed = min }
        speed = (max/speed*min)/10
        
        guard offset < 60 else { dismissVC(); return }
        guard offset > 0 else { return }
        
        // Come back after pull animation
        UIView.animate(withDuration: speed, animations: {
            scrollView.frame.origin.y = self.scrollViewOriginalYPosition
            self.scrollView.contentOffset.y = 0
        })
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        
        let offset = scrollView.frame.origin.y - scrollViewOriginalYPosition
        guard offset > 0 else { return }
        
        // Come back after pull animation
        UIView.animate(withDuration: 0.1, animations: {
            scrollView.frame.origin.y = self.scrollViewOriginalYPosition
            self.scrollView.contentOffset.y = 0
        })
    }
    
}

Some tips: You could try to save the position of the first touch and block the scroll in the scrollviewdidscroll() method if the offset is > 0 and the starting position is inside the card content (BackgroundIV)

PaoloCuscela avatar Apr 02 '19 15:04 PaoloCuscela

OK because I am trying t get the card animation to look exactly like that on the app store where you can only dismiss the detail view controller by scrolling on the image view, no the whole content because then the user can easily/accidentally dismiss the view controller.

arinasawa avatar Apr 02 '19 17:04 arinasawa