Giter Site home page Giter Site logo

floatingpanel's Introduction

FloatingPanel

FloatingPanel is a simple and easy-to-use UI component for a new interface introduced in Apple Maps, Shortcuts and Stocks app. The new interface displays the related contents and utilities in parallel as a user wants.

Maps Stocks

Maps(Landscape)

Features

  • Simple container view controller
  • Fluid animation and gesture handling
  • Scroll view tracking
  • Common UI elements: Grabber handle, Backdrop and Surface rounding corners
  • 2 or 3 anchor positions(full, half, tip)
  • Layout customization for all trait environments(i.e. Landscape orientation support)
  • Behavior customization
  • Free from common issues of Auto Layout and gesture handling

Examples are here.

Requirements

FloatingPanel is written in Swift 4.2. Compatible with iOS 10.0+

Installation

CocoaPods

FloatingPanel is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'FloatingPanel'

Carthage

For Carthage, add the following to your Cartfile:

github "scenee/FloatingPanel"

Getting Started

import UIKit
import FloatingPanel

class ViewController: UIViewController, FloatingPanelControllerDelegate {
    var fpc: FloatingPanelController!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Initialize a `FloatingPanelController` object.
        fpc = FloatingPanelController()

        // Assign self as the delegate of the controller.
        fpc.delegate = self // Optional

        // Add a content view controller.
        let contentVC = ContentViewController()
        fpc.show(contentVC, sender: nil)

        // Track a scroll view(or the siblings) in the content view controller.
        fpc.track(scrollView: contentVC.tableView)

        // Add the views managed by the `FloatingPanelController` object to self.view.
        fpc.add(toParent: self)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // Remove the views managed by the `FloatingPanelController` object from self.view.
        fpc.removeFromParent()
    }
    ...
}

Usage

Move a positon with an animation

Move a floating panel to the top and middle of a view while opening and closeing a search bar like Apple Maps.

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        ...
        fpc.move(to: .half, animated: true)
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        ...
        fpc.move(to: .full, animated: true)
    }

Make your contents correspond with FloatingPanel behavior

class ViewController: UIViewController, FloatingPanelControllerDelegate {
    ...
    func floatingPanelWillBeginDragging(_ vc: FloatingPanelController) {
        if vc.position == .full {
            searchVC.searchBar.showsCancelButton = false
            searchVC.searchBar.resignFirstResponder()
        }
    }

    func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) {
        if targetPosition != .full {
            searchVC.hideHeader()
        }
    }
    ...
}

Support your landscape layout with a FloatingPanelLayout object

class ViewController: UIViewController, FloatingPanelControllerDelegate {
    ...
    func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? {
        return (newCollection.verticalSizeClass == .compact) ? FloatingPanelLandscapeLayout() : nil
    }
    ...
}

class FloatingPanelLandscapeLayout: FloatingPanelLayout {
    public var initialPosition: FloatingPanelPosition {
        return .tip
    }
    public var supportedPositions: [FloatingPanelPosition] {
        return [.full, .tip]
    }

    public func insetFor(position: FloatingPanelPosition) -> CGFloat? {
        switch position {
            case .full: return 16.0
            case .tip: return 69.0
            default: return nil
        }
    }

    public func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint] {
        return [
            surfaceView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuid.leftAnchor, constant: 8.0),
            surfaceView.widthAnchor.constraint(equalToConstant: 291),
        ]
    }
}

Modify your floating panel's interaction with a FloatingPanelBehavior object

class ViewController: UIViewController, FloatingPanelControllerDelegate {
    ...
    func floatingPanel(_ vc: FloatingPanelController, behaviorFor newCollection: UITraitCollection) -> FloatingPanelBehavior? {
        return FloatingPanelStocksBehavior()
    }
    ...
}
...

class FloatingPanelStocksBehavior: FloatingPanelBehavior {
    var velocityThreshold: CGFloat {
        return 15.0
    }

    func interactionAnimator(to targetPosition: FloatingPanelPosition, with velocity: CGVector) -> UIViewPropertyAnimator {
        let damping = self.damping(with: velocity)
        let springTiming = UISpringTimingParameters(dampingRatio: damping, initialVelocity: velocity)
        return UIViewPropertyAnimator(duration: 0.5, timingParameters: springTiming)
    }
    ...
}

Create an additional floating panel for a detail

class ViewController: UIViewController, FloatingPanelControllerDelegate {
    var searchPanelVC: FloatingPanelController!
    var detailPanelVC: FloatingPanelController!

    override func viewDidLoad() {
        // Setup Search panel
        self.searchPanelVC = FloatingPanelController()

        let searchVC = SearchViewController()
        self.searchPanelVC.show(searchVC, sender: nil)
        self.searchPanelVC.track(scrollView: contentVC.tableView)

        self.searchPanelVC.add(toParent: self)

        // Setup Detail panel
        self.detailPanelVC = FloatingPanelController()

        let contentVC = ContentViewController()
        self.detailPanelVC.show(contentVC, sender: nil)
        self.detailPanelVC.track(scrollView: contentVC.scrollView)

        self.detailPanelVC.add(toParent: self)
    }
    ...
}

Author

Shin Yamamoto [email protected]

License

FloatingPanel is available under the MIT license. See the LICENSE file for more info.

floatingpanel's People

Contributors

scenee avatar

Watchers

James Cloos avatar Kristoff IBell avatar

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.