GithubHelp home page GithubHelp logo

boscojwho / sheetinteraction Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 1.0 217 KB

Observe changes to a UISheetPresentationController sheet's position, and perform percent-driven animations driven by a sheet stack's position.

License: GNU General Public License v3.0

Swift 99.59% Objective-C 0.41%

sheetinteraction's Introduction

SheetInteraction

Swift 5.7 License

About

SheetInteraction allows developers to observe changes to a UISheetPresentationController sheet's position, and perform percent-driven animations driven by a sheet stack's position.

Note: This solution is limited to UIKit projects running on iOS devices in compact horizontal size class (i.e. iPhone, or iPad mini running in portrait mode).

Developers may wish to perform percent-driven animations when users interact with UISheetPresentationController's modal sheet stack. Unfortunately, UISheetPresentationController only notifies its delegate when a sheet's detent finishes changing (i.e. when a sheet finishes animating to its target detent). What developers may wish to know is how much a sheet has animated between its smallest and largest detents, as well as between each individual detent, and be notified of that information interactively as those changes occur.

SheetInteraction provides developers with the following features:

  • Track amount a sheet has animated from its smallest to largest detents (as a percentageTotal from 0-1).
  • Track amount a sheet has animated between each detent using a value between 0-1 (e.g. 0.33 animated betweeen medium and large).
  • Observe the target detent at which a sheet will rest when user ends interaction (i.e. on touch up) and before sheet begins animating to its final resting detent.

The above features allow developers to tie user interface animations and state to a sheet's user interaction using animation APIs specified in the Animations section below.

Example

A working example is provided in this project's Sources/Example directory. Build and run the SheetInteraction-Example scheme to see it in action.

How to Use

  1. Initialize a SheetInteraction object.
  2. Assign a delegate to that object in order to observe user interaction.
  3. Set a delegate on SheetInteraction.sheetInteractionGesture, and ensure it simultaneously recognizes with all other gesture recognizers.
  4. See Animations on how to drive percent-driven animations based on a sheet's user interaction.

To begin, initialize a SheetInteraction object on the root view controller of a modal view controller stack. The root view controller can either be a UINavigationController or UIViewController. This object must be initialized with the root view of the root view controller. In a navigation controller setup, ensure this is a view that includes the navigation bar (Warning: Do not use a modal view stack's drop shadow view provided by UIKit, as its frame and safeAreaInsets may not necessarily align with that of the sheetView's).

SheetInteraction only needs to be initialized once for any modal view stack.

Once initialized, set SheetInteraction.sheetInteractionGesture.delegate, and implement gestureRecognizer(shouldRecognizeSimultaneouslyWith...) such that sheetInteractionGesture always recognizes simultaneously with any other gesture.

Finally, set SheetInteraction.delegate, and implement SheetInteractionDelegate in order to drive user-interface changes while user interaction is happening.

Animations

On interaction change, to make user-interface updates that vary according to the current detent, use sheetInteraction.animating(<detentToAnimateWith>, interactionChange: interactionChange). The animation block provides a percentageAnimating value that ranges from 0-1, where 0 is equal to the next smallest detent, and 1 is equal to the specified detent. In other words, this value approaches 1 when user is moving the sheet to a larger detent, and vice-versa.

On interaction change, use the value interactionChange.percentageTotal to make user-interface updates that vary based on a sheet's overall position relative to its window.

On interaction end, use sheetInteraction.sheetController.detent(withIdentifier: targetDetentInfo.detentIdentifier) to get the target detent. You may also wish to use the custom detent.greaterThan(<anotherDetent>) comparison function to make user-interface updates that are applicable to more than one detent. For example:

if targetDetent.greaterThan(.mediumSmall(), in: sheetInteraction.sheetController) == true {
    /// e.g. Show or hide user-interface element(s) that only apply to detents larger than `mediumSmall()`.
}

Limitations

  • SheetInteraction cannot be used with UIKit system detents. You must create custom detents using Detent.custom(...). If not, your sheet will crash on _containerBounds.
  • Do not set UISheetPresentationController.prefersGrabberVisible = true. UIKit's default grabber view steals touches from SheetInteraction.

Handling keyboard events:

  • UISheetPresentationController does not update selectedDetentIdentifier when keyboard (dis)appears via user interaction or programmatic change. This is true when using system detents, custom detents, or a mix of both.
  • To properly respond to sheet detent changes triggered by keyboard (dis)appearance:
  1. ......

Under-the-Hood

SheetInteraction adds a pan gesture recognizer to the sheetView provided to it. That pan gesture is what enables SheetInteraction to determine when a user begins, changes, and ends interacting with a modal sheet.

During the begin and end phases, SheetInteraction relies on the sheetView's UISheetPresentationController to provide it with the currently selected detent.

During the change phase, SheetInteraction uses the sheet's layout metrics provided by SheetLayoutInfo to generate a set of detentLayoutInfo for all active detents. SheetLayoutInfo is a set of layout measurements for the sheet relative to the sheet's window (apart from the sheet's frame, this is mostly static layout data). The set of detentLayoutInfo is specific to each active detent, and is only valid during user interaction.

sheetinteraction's People

Contributors

boscojwho avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

odnoletkov

sheetinteraction's Issues

targetDetent is wrong on pan end, if pan gesture begins on a scroll view.

When prefersScrollingExpandsWhenScrolledToEdge == true, and sheet interaction begins on a scroll view, UISheetPresentationController.selectedDetentIdentifier doesn't immediately reflect where sheet will rest on user interaction end (i.e. touch up).

UISheetPresentationController.selectedDetentIdentifier does immediately reflect end state when user interaction begins on a non-scroll view.

Sheet interaction isn't notified when another sheet is dismissed using swipe gesture.

When two or more modal sheets are presented, and user quickly swipes to close the top sheet, iOS may automatically move the now top-most sheet to a detent it deems appropriate.

When that happens, we need to figure out how to observe that change, and notify SheetInteraction's delegate.

Currently, the delegate isn't notified, and user-interface state may not reflect the actual selected detent.

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.