Home
Softono

ContainerController

Open source MIT Swift
501
Stars
47
Forks
5
Issues
11
Watchers
1 year
Last Commit

 About ContainerController

👉↕️📱ContainerController 🧩✨⚙️ is a UI Component Swipe-Panel (Customizable). 💡 The idea is copied from the app: Apple Maps, Stocks. Swift version

Platforms

Web Self-hosted macOS iOS

Languages

Swift

Links

Need Help Installing ContainerController?

We provide expert installation service for this software. Our team will install, configure, and secure ContainerController on your server. plans start at just $30.

ContainerController

View on GitHub

image(Landscape)

ContainerController

Version License Platform Swift 5.0 Swift 5.1 Swift 5.2

UI Component. This is a copy swipe-panel from app: https://www.apple.com/ios/maps/

It can:

  • Animately move top / middle / bottom
  • Add multiple ContainerControlleron top of each other in self.view
  • Add any type of ScrollView: Table / Collection / Text
  • Control Gesture or Scroll
  • Pin HeaderView to top / pin FooterView to bottom,
  • Add Background Color / background blur transparency
  • Adjust cornerRadius edges
  • Adjust container shadow
  • When raised to top = Add background shadow -
  • Has the ability to adjust Left / Right margins
  • And adjust Left / Right margins for landscape state.

Preview

image image image(Landscape)

About the project

Examples of use (ui swipe component ContainerController) in popular design applications.

It is used in different categories apps:

  • Maps / Menu / Player Music / Market / Sports News / Taxi / Finance Banks Stock / Wallets / Analytics / Notes
  • Alerts / Popups / Notifications

Features

Requirements

✏️ ContainerController is written in Swift 5.0+. It can be built by Xcode 11 or later. Compatible with iOS 13.0+.

Installation

CocoaPods

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

pod 'ContainerControllerSwift'

Swift Package Manager with Xcode 11

dependencies: [
    .package(url: "https://github.com/mrustaa/ContainerController.git")
]

Follow this doc.

Design examples

Designs are borrowed from Dribbble

To get the design, you need to add a branch ui_examples

git clone https://github.com/mrustaa/ContainerController.git
cd ContainerController/
git checkout ui_examples

URLs Author:

GIF Previews:

image image image image

image image image image

Getting Started


import UIKit
import ContainerControllerSwift

class ViewController: UIViewController, ContainerControllerDelegate {
    
    var container: ContainerController!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create ContainerController Layout object
        let layout = ContainerLayout()
        layout.startPosition = .hide
        layout.backgroundShadowShow = true
        layout.positions = ContainerPosition(top: 70, middle: 250, bottom: 70)
        
        // Create ContainerController object, along with the container.view
        // Pass the current UIViewController 
        let container = ContainerController(addTo: self, layout: layout)
        container.view.cornerRadius = 15
        container.view.addShadow()
        
        // Create subclass scrollView
        let tableView = UITableView()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.delegate = self
        tableView.dataSource = self
        
        // Add scrollView to container
        container.add(scrollView: tableView)
        
        // Finishing settings ContainerController,
        // Animated move position Top
        container.move(type: .top)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        // Remove the subviews ContainerController
        container.remove()
        container = nil
    }
}

Action

Move position with an animation


container.move(type: .top)
container.move(type: .middle)
container.move(type: .bottom)

Adding possible custom subviews in ContainerController view

Add ScrollView


let tableView = UITableView()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.backgroundColor = .clear
tableView.tableFooterView = UIView()
tableView.delegate = self
tableView.dataSource = self

// Add scrollView to container
container.add(scrollView: tableView)

Delegate to self 👆

If you implement delegate ScrollView (TableView, CollectionView, TextView) to self, then you need to call 4 functions in ContainerController

extension ViewController: UIScrollViewDelegate {
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        container.scrollViewDidScroll(scrollView)
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        container.scrollViewWillBeginDragging(scrollView)
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        container.scrollViewDidEndDecelerating(scrollView)
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        container.scrollViewDidEndDragging(scrollView, willDecelerate: decelerate)
    }
}

extension ViewController: UITableViewDelegate {
    ...
}

extension ViewController: UITableViewDataSource {
    ...
}

Add HeaderView


let headerView = ExampleHeaderGripView()
headerView.height = 20

container.add(headerView: headerView)

Add FooterView


let tabBarView = HeaderTabBarView()
tabBarView.height = 49.0

container.add(footerView: tabBarView)

Add Custom View


// Add custom shadow
let layer = container.view.layer
layer.shadowOpacity = 0.5
layer.shadowColor = UIColor.red.cgColor
layer.shadowOffset = CGSize(width: 1, height: 4)
layer.shadowRadius = 5

// Add view in container.view
let viewRed = UIView(frame: CGRect(x: 50, y: 50, width: 50, height: 50))
viewRed.backgroundColor = .systemRed
container.view.addSubview(viewRed)

// Add view under scrollView container.view
let viewGreen = UIView(frame: CGRect(x: 25, y: 25, width: 50, height: 50))
viewGreen.backgroundColor = .systemGreen
container.view.insertSubview(viewGreen, at: 0)

Settings ⚙️

Layout

Customize the layout with create subclass ContainerLayout on initialization


class NewContainerLayout: ContainerLayout {
    
    override init() {
        super.init()
        
        // Initialization start position.
        startPosition = .hide
        
        // Disables any moving with gestures.
        movingEnabled = true
        
        // Sets the new value for positions of animated movement (top, middle, bottom).
        positions = ContainerPosition(top: 70, middle: 250, bottom: 70)
        
        // Sets insets container.view  (left, right).
        insets = ContainerInsets(right: 20, left: 20)
    }
}

class ViewController: UIViewController {

    var container: ContainerController!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        container = ContainerController(addTo: self, layout: NewContainerLayout())
        container.move(type: .top)
    }
}

Or create object ContainerLayout


override func viewDidLoad() {
    super.viewDidLoad()
    
    // Create ContainerController Layout object
    let layout = ContainerLayout()
    layout.startPosition = .hide
    layout.backgroundShadowShow = true
    layout.positions = ContainerPosition(top: 70, middle: 250, bottom: 70)
    
    container = ContainerController(addTo: self, layout: layout)
}

Change settings right away


// Properties
container.set(movingEnabled: true)
container.set(trackingPosition: false)
container.set(footerPadding: 100)

// Add ScrollInsets Top/Bottom
container.set(scrollIndicatorTop: 5) // ↓
container.set(scrollIndicatorBottom: 5) // ↑

// Positions
container.set(top: 70) // ↓
container.set(middle: 250) // ↑
container.set(bottom: 80) // ↑

// Middle Enable/Disable
container.set(middle: 250)
container.set(middle: nil)

// Background Shadow
container.set(backgroundShadowShow: true)

// Insets View
container.set(left: 5) // →
container.set(right: 5) // ←

// Landscape params
container.setLandscape(top: 30)
container.setLandscape(middle: 150)
container.setLandscape(bottom: 70)
container.setLandscape(middle: nil)

container.setLandscape(backgroundShadowShow: false)

container.setLandscape(left: 10)
container.setLandscape(right: 100)

ContainerController View

Use a ready-made solution

ContainerView is generated automatically when you create ContainerController Use a ready-made solution to change the radius, add shadow, and blur.

Change CornerRadius

// Change cornerRadius global for all subviews
container.view.cornerRadius = 15 

Add Layer Shadow

container.view.addShadow(opacity: 0.1) 

Add Background Blur

// add blur UIVisualEffectView
container.view.addBlur(style: .dark) 

More details

Change positions on screen Top Middle Bottom


// These parameters set the new position value.
container.layout.positions = ContainerPosition(top: 70, middle: 250, bottom: 70)

// Change settings right away
container.set(top: 70) // ↓
container.set(middle: 250) // ↑
container.set(bottom: 80) // ↑

Customize indentations for View


// Sets insets container.view  (left, right).
container.layout.insets = ContainerInsets(right: 20, left: 20)

container.layout.landscapeInsets = ContainerInsets(right: 20, left: 100)


// Change settings right away
container.set(left: 5) // →
container.set(right: 5) // ←

container.setLandscape(left: 10)
container.setLandscape(right: 100)

Customize for landscape orientation


// Sets the background shadow under container. (Default: backgroundShadowShow).
container.layout.landscapeBackgroundShadowShow = false

// Sets the new value for positions of animated movement (top, middle, bottom). (Default: positions).
container.layout.landscapePositions = ContainerPosition(top: 20, middle: 150, bottom: 70)

// Sets insets container.view (left, right). (Default: insets).
container.layout.landscapeInsets = ContainerInsets(right: 20, left: 100)


// Change settings right away

container.setLandscape(top: 30)
container.setLandscape(middle: 150)
container.setLandscape(bottom: 70)
container.setLandscape(middle: nil)

container.setLandscape(backgroundShadowShow: false)

container.setLandscape(left: 10)
container.setLandscape(right: 100)

Parameters for control footerView


// Padding-top from container.view, if headerView is added, then its + height is summed.
container.layout.footerPadding = 100

// Tracking position container.view during animated movement.
container.layout.trackingPosition = false

// Change settings right away

container.set(footerPadding: 100)
container.set(trackingPosition: false)

image image

ContainerController Delegate


class ViewController: UIViewController, ContainerControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let container = ContainerController(addTo: self, layout: layout)
        container.delegate = self
    }
}

/// Reports rotation and orientation changes
func containerControllerRotation(_ containerController: ContainerController) {
    ...
}

/// Reports a click on the background shadow
func containerControllerShadowClick(_ containerController: ContainerController) {
    ...
}

/// Reports the changes current position of the container, after its use
func containerControllerMove(_ containerController: ContainerController, position: CGFloat, type: ContainerMoveType, animation: Bool) {
    ...
}

Author

[email protected] 📩| mrustaa JUNE 2020

License

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