Giter Site home page Giter Site logo

drawerview's Introduction

Sample

DrawerView

A drop-in view, to be used as a drawer anywhere in your app.

Sample Sample Sample

Ease of use

DrawerView is a simple drop-in view that you can add to your app. No need to restructure your views or view controllers to add support for it. This also makes it possible to have multiple drawers hosting different content and switch between them the same way it is done in the iOS Maps.

Automatic support for scroll views

DrawerView handles subview interaction so that it adds specialized support for scroll views. What this practically means is that you can add a scroll view (or a table view) inside it and the DrawerView will handle the transition from scrolling the subview to scrolling the drawer.

Customization

Visuals: By default DrawerView supports UIBlurEffect as a background. However, any UIColor is supported too. Just remember to set backgroundEffect to nil. Besides background, corner radius, borders and shadow can be customized as well.

Position: The drawer has four distinct positions: closed, collapsed, partiallyOpen, open. Each of these positions can be customized and you can define the enabled positions. Open position is evaluated using systemLayoutSizeFitting and constrained by the given topMargin.

Bottom Inset: To support iOS devices with a notch at the bottom of the screen, you can change insetAdjustmentBehavior to automatically determine the correct inset. You can also set it to use the safe area of the superview or set it to a fixed value. Due to the content being overlapping with the notch you can change contentVisibilityBehavior to define which views should be hidden when collapsed. By default these two properties are set to automatic.

Visibility: You can also set the visibility of the drawer. This is a distinct property from position, but acts the same way as if the drawer was closed. The purpose of this is to help you so that you don't have to remember the previous position if the drawer is made visible again. This in turn makes it convenient to have multiple drawers but only one visible at a time.

Installation

You can install DrawerView with Carthage and CocoaPods. With CocoaPods, add the following into your Podfile:

pod "DrawerView"

For Carthage add the following into your Cartfile:

github "mkko/DrawerView"

Usage

DrawerView tries automatically to occupy the view it will be added to. It uses autolayout to set its position, and thus you can attach views to it You can set it up with storyboards or programmatically

Setting things up

Here's listed the possible ways of setting things up. Hands-on examples of setting things up can be found from the included example project.

Set up in storyboards

Storyboard is supported in two ways: as an embedded view and as a child view controller.

As child view controller

You can add contents of one view controller as a drawer to another view controller, almost the same way as you would use "Container View".

  1. Create the two view controllers.
  2. Define a storyboard ID for the drawer view controller (eg. "DrawerViewController")
  3. Make the connection in code:
override func viewDidLoad() {
    super.viewDidLoad()

    let drawerViewController = self.storyboard!.instantiateViewController(withIdentifier: "DrawerViewController")
    self.addDrawerView(withViewController: drawerViewController)
}
As embedded view
  1. Create a view in storyboard that is not inside the view controller view hierarchy. To do this, you can for instance drag a new view directly to the document outline.
  2. Set a custom class of the view to a DrawerView.
  3. Connect the containerView IBOutlet of the newly created view to the view where you want it to be added (e.g. the view controller root view).

Set up programmatically

Programmatic setup is pretty much the same as setting up any UIView: you create one, set it up with subviews and add it to a view. Here's an example to do it.

override func viewDidLoad() {
    super.viewDidLoad()

    let drawerView = DrawerView()
    drawerView.attachTo(view: self.view)

    // Set up the drawer here
    drawerView.snapPositions = [.collapsed, .partiallyOpen]
}

drawerview's People

Contributors

cjwillis809 avatar decanus avatar grangej avatar ikloo avatar kylegoslan avatar mikedinicola avatar mkko avatar nickwph avatar wyszo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

drawerview's Issues

Drawer does not change size on pan

First of all thanks for your great work!

I have a problem when panning the drawer.
In your example project the drawer grows and shrinks when panning up or down.
In my app nothing happens when I start panning. Only when the panning finishes the drawer opens or collapses.

Do you have an idea what I'm doing wrong?

Here is how I'm adding the drawer:

` boxMapDrawerViewController.view.cornerRadius = 8

    drawerView = addDrawerView(withViewController: boxMapDrawerViewController)
    drawerView?.snapPositions = [.open, .collapsed]
    drawerView?.setPosition(.collapsed, animated: false)
    drawerView?.collapsedHeight = 130
    drawerView?.backgroundEffect = nil
    drawerView?.shadowRadius = 20
    drawerView?.shadowOpacity = 0.25

`

The boxMapDrawerViewController only contains a one simple UIView, I also tried one with a scroll view inside. It does not make a difference adding the drawer in loadView or viewDidLoad.

I can't see what I'm doing different in comparison to your sample app.

Btw, I'm using Xcode 10.2.1, Swift 5 and deployment target is 12.0. Version of DrawerView is 1.1.1.

Attach drawer below specific view

Hello @mkko! I have a question. Is it possible to insert drawer below specific view?

I have UITabBarController with some items inside it. I want to present drawer below UITabBar but on front of my UIViewControllers.

Make DrawerView extensible

Any chance you could make the DrawerView class open this would allow extending it and setting up the view within a subclass itself.

New tagged release?

Can we get a new tagged release, please?

In our project we're using an internal fork - but the fixes we made are already backported to the main repo and merged in. We'd like to ditch the fork, but we're not comfortable doing this unless there's a tagged release (we don't want to put a commit hash in a Podfile).

Any chance of getting current version released?

iOS 13 - Impossible to scroll up and down

Hello!
There's this annoying bug that prevent to scroll the drawer up and down, unless you put the finger on the table view inside it. This happens only on iOS 13.
I think it's pretty urgent. Do you think you're able to release a fix soon?

Thanks.

Memory Leak in DrawerView.scrollToPosition

This hasn't produced a crash for me, but I thought you'd like to know anyway in case someone else does run into a related bug. I found this while profiling my own app. Let me know if you need any more info!

Version

Installed using pod 'DrawerView', '~> 1.3.1'

Profiler Screenshot

Screen Shot 2020-02-11 at 5 41 01 PM

Identified Line

Screen Shot 2020-02-11 at 5 43 01 PM

Swipe to delete in UITableView

Hello!
Congratulations for the very cool and useful library!

I'm facing an issue, related to the swipe to delete. I have a UITableView into the drawer and the user should be able to delete cells swiping. This is not working good as the drawer is easily draggable. Is there a way to adjust the sensibility of the scroll? Or is there another way?

Fatal Exception: NSInternalInconsistencyException

Fatal Exception: NSInternalInconsistencyException
It is an error to release a paused or stopped property animator. Property animators must either finish animating or be explicitly stopped and finished before they can be released.
DrawerView.scrollToPosition(_:animated:notifyDelegate:completion:)

DrawerView.swift - Line 582
DrawerView.scrollToPosition(_:animated:notifyDelegate:completion:) + 582

Unable to subclass DrawerView

I have a need to override some functions for customization. However Xcode won’t let me do this because: ‘Cannot inherit from non-open class (DrawerView) outside of its defining module’.

Could you please declare DrawerView as ‘open’ instead of ‘public’?

How to work with UISlider?

Hi, I have a drawerview which contains two views embedded in a UIScrollView.
There is an UISlider in the first view, how can I stop the drawer scrolling when I panning the UISlider back and forth?

Cocoapods version is out of date

Love this project, but it looks like the cocoapods version is missing some critical new features, for example, overlayBackgroundColor. Can you please update? Thanks!

Collection behaves buggy when I am adding as a subview

Hi,
First of all, thank you for providing us a great tool, here is the issue I am facing when I am adding a Horizontal collection view as a subview of a drawer view When I am trying to scroll the collection view drawer gets changed its states.

Swift 5 Support

Hello,

My team is interested in using this library but we are also looking to upgrade our codebase to Swift 5 (using Swift 4.2 currently). Will this support projects that are running Swift 5? I ran the Swift 5 conversion tool that Xcode provides and there were a couple changes made in DrawerView.swift, mainly around the firstIndex calls.

Thanks.

Top constraints for iPhone X

Thank you very much for creating this drawer. Really useful for my project.

The only thing I'm having a bit of trouble is when I'm displaying the drawer in a collapsed state. The constraints are different when viewing it in an iPhone X.

I have the top constraints to 5px in my drawer view controller. It looks fine on an iPhone 8 Plus but seems to look different on the iPhone X. I have also tried to set the constraints to the safe area and the superview to see if there's a difference but got the same result.

Do I need to update or adjust the constraints when I add the drawer view with the view controller I created?

VisualEffectView should be opt out not opt in

Thanks for your great work!, I think visual effect should be disabled by default unless we turn on it. In my drawer view, i need to make the background color to be clear, and the visual effect is messing up even I set backgroundEffect to nil

CollectionView scrolls to top when I open the drawer

So I'm using the drawer as a "Settings" view, and it is pulled up over a CollectionView. When I open the Settings drawer, if I had scrolled at all in the CollectionView beforehand, it scrolls it back to the top. Any way to fix this?

Horizontal scrolling in any state but open

It seems that in the most recent version of your code, the ability to horizontally scroll when the DrawerView is in any other position but open does not work.

I noticed that this functionality is part of your demo app, but it does not function outside of your demo app.

How to disable top darkening

Hello, first thanks so much for creating this framework, it's been very useful in my project.

I searched the documentation and code, but I didn't find it.

How do I turn off this animation that makes the top part dark when I scroll the drawer to the top of my screen? it's possible?

Cannot reliably scroll horizontally with nested scrollView

I use the DrawerViewto host my SwiftUI views like so:

VStack{
  ScrollView(.vertical){
    ScrollView(.horizontal){
      AnyView()
    }
  }
}

Trouble is, unless I scroll perfectly horizontally, the drawer view tries to close/open if my finger moves up or down slightly.

This will even happen when the parent ScrollView(.vertical) is scrolled to the bottom, meaning I will end up with a collapsed drawer view but the ScrollView(.vertical) won't be scrolled to the top.

horizontal scroll in collectionView

Hello, i can't horizontal scroll in collectionView - drawerView starts to change position, when i try scroll collectionView. I need to scroll the collectionView in any position

drawer(_ drawerView: DrawerView, didTransitionTo position: DrawerPosition) delegate method not always called

Just diving into this bug I have found. In my app, I want to change logic depending if the user has swiped the drawer closed. I basically pop up a UI element that allows them to reopen the drawer since closed in my app is completely closed. I have this logic in the drawer(_ drawerView: DrawerView, didTransitionTo position: DrawerPosition) delegate method checking if position == .closed. I have found that if the user swiped multiple times in quick succession, this delegate method will not fire even though the drawer does indeed transition to the .closed position. willTransitionTo does fire, so as a workaround I am changing to listen to that.

Steps to reproduce:

  1. Clone and run DrawerViewExample app
  2. Run the app on a physical device (easier to reproduce this way, but can also happen in sim)
  3. Swipe the drawer up multiple times in quick succession
  4. Observe console logs

Expected: (These logs are from swiping up once)

drawerWillBeginDragging
drawerWillEndDragging
drawer(_:willTransitionFrom: partiallyOpen to: open)
drawerView(_:didTransitionTo: open)

Actual:

drawerWillBeginDragging
drawerWillEndDragging
drawer(_:willTransitionFrom: partiallyOpen to: open)
drawerWillBeginDragging
drawerWillBeginDragging
drawerWillBeginDragging
drawerWillBeginDragging

In collecting these logs, I notice that there are several drawerWillBeginDragging events without corresponding drawerWillEndDragging events. Perhaps this is a good starting point.

Any support of Privacy Manifest?

Following definition of "third-party SDKs" that as mentioned in the WWDC23. and according to Privacy manifest files | Apple Developer Documentation, I think this library may also require a Privacy Manifest for the upcoming app review in Spring 2024.

Do you have any plans to add a Privacy Manifest or to have a claim that this library actually does not need a Privacy Manifest?

Thank you very much!

WKWebview Support

Would be nice for DrawerView (which is amazing btw) to support swipe to dismiss for WKWebViews. Would also be nice if WKWebView was a subclass of UIScrollView!

DrawerView sometimes disappears in collapsed position

I'm having trouble with disappearing DrawerView. I have a scrollable UITableView as DrawerView's subview and it generally works fine, but sometimes when its collapsed it just disappears when I drag it down...its there but becomes invisible(not changing alpha or hiding it anywhere)..

In order for it to show I have to drag it up from collapsed position(even though I don't see it) and it will appear again.
It's been bugging me for a while and I don't know how to solve it.

Any ideas if I could be doing something wrong with setting up the DrawerView?

In any case, great job creating the DrawerView and thank you.

Dismiss Overlay gesture not working when voice over enabled

The Overlay wasn't working when accessibility voice over enabled.

As per the native methods the Overlay enable the accessibility in order to work as normal when voice over enabled.

Please enable the accessibility for Overlay view class

isAccessibilityElement = true

childReachedTheTop calculation ignores contentInset

I have a DrawerView with a descendent UITableView inside a containerView. That tableview extends under a sibling header view so that the header can be collapsed to reveal more of the tableview on scroll. (Similar to how Apple collapses the Navigation Bar to show more content when you scroll).

To achieve this I set a contentInset for the top of the tableview so content can be fully exposed while the header view is fully expanded.

tableview.contentInset = UIEdgeInset(top:175, left:0, bottom:view.safeAreaInsets.bottom, right:0)

However, DrawerView's handlePan() is not taking the content inset into account when determining if there is more content in the scrollview to be shown

The fix is to change the line 810 in DrawerView:

let childReachedTheTop = activeScrollViews.contains { $0.contentOffset.y <= 0 }

to:

let childReachedTheTop = activeScrollViews.contains { $0.contentOffset.y <= -$0.contentInset.top }

and this also necessitates a change to line 837:

let minContentOffset = activeScrollViews.map { $0.contentOffset.y }.min() ?? 0

to

let minContentOffset = activeScrollViews.map { $0.contentOffset.y + $0.contentInset.top}.min() ?? 0

Happy to make a pull request with the fix, but need to take a look at the unit test setup you have first, if it even something you'd want to add a unit test for.

Great component BTW!

Crash with v1.2.1

Hi,

first of all thanks for your great work!

After updating from version 1.2.0 to 1.2.1 I'm getting a crash when calling

drawerView?.insetAdjustmentBehavior = .fixed(AppDelegate.shared.window?.safeAreaInsets.bottom ?? 0)

It does not matter calling this in loadView() or viewDidLoad().

Do you have an idea why this happens?

Is it possible to attach this to the top of a Tab Bar?

Hi,
Sorry for the request-for-help disguised as an issue.

I'm trying to emulate the podcasts and itunes' app behaviors with DrawerView. This means that I have a "now playing" bar that sits on top of a tab bar, and doesn't change when you switch tabs, which can be expanded with a tap or a swipe.

To that end, I've tried attaching a DrawerView in code (in UITabBarController), trying to add layout constraints to attach the bottom of the drawer view to the top of the tab bar, but any layout constraint I add seems to get rejected immediately. I'm trying this:

class TabBarControllerWithDrawer : UITabBarController {

   override func viewDidLoad() {
        let drawerView = DrawerView()
        drawerView.attachTo(view: self.view)
        drawerView.snapPositions = [.collapsed, .open]

        NSLayoutConstraint(item: drawerView, attribute: .bottom, relatedBy: .equal, toItem: self.tabBar, attribute: .top, multiplier: 1, constant: 0).isActive = true
}

Am I totally on the wrong track? Should I instead be just attaching a shared instance of DrawerView to each of the tab's children? Some other method?

Thanks,
Ben

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.