Pulley icon indicating copy to clipboard operation
Pulley copied to clipboard

Support dimming when partially revealed

Open triztian opened this issue 4 years ago • 2 comments

Is it possible to toggle the primaryContentViewController dimming when the drawer is partially revealed?, I know it gets dimmed when in .open. I'm looking to be able to do something like this:

let pulley = PulleyViewController()

pulley.setDrawerPosition(.partiallyRevealed)
pulley.dimPrimaryContent = true

Having a property that toggles dimming would be great, another potential solution would be for the PulleyDrawerViewControllerDelegate to have a openDrawerHeight(bottomSafeArea:) method that provides height for the .open position this way we could make it the desired size with dimming.

triztian avatar May 28 '20 19:05 triztian

I'm looking for the exact same functionality, @triztian did you managed to work out something?

iori57 avatar Dec 01 '20 05:12 iori57

@iori57 Yes, I created a "Dimmable" protocol and extended PulleyController to check for that type; it is that type It'll inject a view to the primary controller. It's roughly like this:

protocol DimmableViewController: AnyObject {
    var isDimmed: Bool { get set }
    var dimAnimationDuration: TimeInterval { get set }
    var dimOpacity: CGFloat { get set }
    var dimColor: UIColor { get set }
}

Here's my base dimmable controller that I extend:

class BaseDimmableViewController: UIViewController, DimmableViewController {
    private(set) lazy var dimOverlayView: UIView = {
        let overlay = UIView(frame: view.frame)
        overlay.translatesAutoresizingMaskIntoConstraints = false
        overlay.backgroundColor = dimColor
        overlay.alpha = dimOpacity
        overlay.tag = 42
        return overlay
    }()

    private(set) lazy var dimNavbarOverlay: UIView? = {
        guard let navBarViewFrame = navigationController?.view.frame else { return nil }
        let overlay = UIView(frame: navBarViewFrame)
        overlay.translatesAutoresizingMaskIntoConstraints = false
        overlay.backgroundColor = dimColor
        overlay.alpha = dimOpacity
        overlay.tag = 43
        return overlay
    }()

    var isDimmed: Bool = false {
        didSet {
            if isViewLoaded && isDimmed {
                if dimAnimationDuration > 0.0 {
                    dimOverlayView.alpha = 0.0
                }

                if let navBarView = navigationController?.view,
                    let dimNavbarOverlay = dimNavbarOverlay {
                    if dimAnimationDuration > 0.0 {
                        dimNavbarOverlay.alpha = 0.0
                    }
                    navBarView.addSubview(dimNavbarOverlay)
                } else {
                    view.addSubview(dimOverlayView)
                }

                UIView.animate(withDuration: dimAnimationDuration) {
                    self.dimOverlayView.alpha = self.dimOpacity
                    self.dimNavbarOverlay?.alpha = self.dimOpacity
                }
            } else {
                if dimAnimationDuration <= 0.0 {
                    if let navBarView = navigationController?.view,
                        navBarView.subviews.last?.tag == 43 {
                        navBarView.subviews.last?.removeFromSuperview()
                    } else {
                        if view.subviews.last?.tag == 42 {
                            view.subviews.last?.removeFromSuperview()
                        }
                    }
                } else {
                    let contentOverlay = self.view.subviews.last
                    let navOverlay = self.navigationController?.view.subviews.last

                    UIView.animate(withDuration: dimAnimationDuration, animations: {
                        if contentOverlay?.tag == 42 {
                            contentOverlay?.alpha = 0.0
                        }

                        if navOverlay?.tag == 43 {
                            navOverlay?.alpha = 0.0
                        }
                    }, completion: { _ in
                        if contentOverlay?.tag == 42 {
                            contentOverlay?.removeFromSuperview()
                        }

                        if navOverlay?.tag == 43 {
                            navOverlay?.removeFromSuperview()
                        }
                    })
                }
            }
        }
    }

    var dimAnimationDuration: TimeInterval = 0.3
    var dimOpacity: CGFloat = 0.3

    var dimColor: UIColor = .black
}

And finally my custom PulleyController:

class DimmingPulleyViewController: PulleyViewController {
   var dimPartiallyRevealed = false 

   override func setDrawerPosition(position: PulleyPosition, 
                                                           animated: Bool, 
                                                           completion: PulleyAnimationCompletionBlock? = nil) {
      if dimPartiallyRevealed, let dimmableController = primaryContentViewController as? DimmableViewController {
         dimmableController.isDimmed = position == .partiallyRevealed
         // `.open` will be handled by the `PulleyViewController`
      } 

      super.setDrawerPosition(position: position, animated: animated, completion: completion)
   }
}

triztian avatar Dec 03 '20 05:12 triztian