GithubHelp home page GithubHelp logo

ivanvorobei / spstorkcontroller Goto Github PK

View Code? Open in Web Editor NEW
2.7K 38.0 201.0 17.93 MB

Now playing controller from Apple Music, Mail & Podcasts Apple's apps.

Home Page: https://opensource.ivanvorobei.io

License: MIT License

Ruby 0.06% Swift 99.81% Objective-C 0.13%
controller apple music mail app ui similar mimicrate animation pop

spstorkcontroller's Introduction

SPStorkController

About

Controller as in Apple Music, Podcasts and Mail apps. Help if you need customize height or suppport modal style in iOS 12.

Simple adding close button and centering arrow indicator. Customizable height. Using custom TransitionDelegate.

Alert you can find in SPAlert project. It support diffrents presets, some animatable.

If you like the project, don't forget to put star ★ and follow me on GitHub:

Navigate

Requirements

Swift 4.2 & 5.0. Ready for use on iOS 10+

Installation

CocoaPods:

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate SPStorkController into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'SPStorkController'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate SPStorkController into your Xcode project using Carthage, specify it in your Cartfile:

github "ivanvorobei/SPStorkController"

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

To integrate SPStorkController into your Xcode project using Xcode 11, specify it in Project > Swift Packages:

https://github.com/ivanvorobei/SPStorkController

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate SPStorkController into your project manually. Put Source/SPStorkController folder in your Xcode project. Make sure to enable Copy items if needed and Create groups.

Quick Start

Create controller and call func presentAsStork:

import UIKit
import SPStorkController

class ViewController: UIViewController {
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let controller = UIViewController()
        self.presentAsStork(controller)
    }
}

If you want customize controller (remove indicator, set custom height and other), create controller and set transitioningDelegate to SPStorkTransitioningDelegate object. Use present or dismiss functions:

let controller = UIViewController()
let transitionDelegate = SPStorkTransitioningDelegate()
controller.transitioningDelegate = transitionDelegate
controller.modalPresentationStyle = .custom
controller.modalPresentationCapturesStatusBarAppearance = true
self.present(controller, animated: true, completion: nil)

Please, do not init SPStorkTransitioningDelegate like this:

controller.transitioningDelegate = SPStorkTransitioningDelegate()

You will get an error about weak property.

Usage

Light StatusBar

To set light status bar for presented controller, use preferredStatusBarStyle property. Also set modalPresentationCapturesStatusBarAppearance. See example:

import UIKit

class ModalViewController: UIViewController {
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

Custom Height

Property customHeight sets custom height for controller. Default is nil:

transitionDelegate.customHeight = 350

Close Button

Property showCloseButton added circle button with dismiss action. Default is false:

transitionDelegate.showCloseButton = false

Arrow Indicator

On the top of controller you can add arrow indicator with animatable states. It simple configure. Property showIndicator shows or hides top arrow indicator. Default is true:

transitionDelegate.showIndicator = true

Property Parameter indicatorColor for customize color of arrow. Default is gray:

transitionDelegate.indicatorColor = UIColor.white

Property hideIndicatorWhenScroll shows or hides indicator when scrolling. Default is false:

transitionDelegate.hideIndicatorWhenScroll = true

You can set always line or arrow indicator. Set indicatorMode:

transitionDelegate.indicatorMode = .alwaysLine

Dismissing

You can also configure events that will dimiss the controller. Property swipeToDismissEnabled enables dismissal by swipe gesture. Default is true:

transitionDelegate.swipeToDismissEnabled = true

Property translateForDismiss sets how much need to swipe down to close the controller. Work only if swipeToDismissEnabled is true. Default is 240:

transitionDelegate.translateForDismiss = 100

Property tapAroundToDismissEnabled enables dismissal by tapping parent controller. Default is true:

transitionDelegate.tapAroundToDismissEnabled = true

Corner Radius

Property cornerRadius for customize corner radius of controller's view. Default is 10:

transitionDelegate.cornerRadius = 10

Haptic

Property hapticMoments allow add taptic feedback for some moments. Default is .willDismissIfRelease:

transitionDelegate.hapticMoments = [.willPresent, .willDismiss]

Snapshots

The project uses a snapshot of the screen in order to avoid compatibility and customisation issues. Before controller presentation, a snapshot of the parent view is made, and size and position are changed for the snapshot. Sometimes you will need to update the screenshot of the parent view, for that use static func:

SPStorkController.updatePresentingController(modal: controller)

and pass the controller, which is modal and uses SPStorkTransitioningDelegate.

If the parent controller scrollings and you try to show SPStorkController, you will see how it froze, and in a second its final position is updated. I recommend before present SPStorkController stop scrolling force:

scrollView.setContentOffset(self.contentOffset, animated: false)

Navigation Bar

You may want to add a navigation bar to your modal controller. Since it became impossible to change or customize the native controller in swift 4 (I couldn’t even find a way to change the height of the bar), I had to recreate navigation bar from the ground up. Visually it looks real, but it doesn’t execute the necessary functions:

import UIKit
import SPFakeBar

class ModalController: UIViewController {
    
    let navBar = SPFakeBarView(style: .stork)
        
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.white

        self.navBar.titleLabel.text = "Title"
        self.navBar.leftButton.setTitle("Cancel", for: .normal)
        self.navBar.leftButton.addTarget(self, action: #selector(self.dismissAction), for: .touchUpInside)

        self.view.addSubview(self.navBar)
    }
}

You only need to add a navigation bar to the main view, it will automatically layout. Use style .stork in init of SPFakeBarView. Here is visual preview with Navigation Bar and without it:

To use it, you need to install SPFakeBar pod:

pod 'SPFakeBar'

Working with UIScrollView

If you use UIScrollView (or UITableView & UICollectionView) on controller, I recommend making it more interactive. When scrolling reaches the top position, the controller will interactively drag down, simulating a closing animation. Also available close controller by drag down on UIScrollView. To do this, set the delegate and in the function scrollViewDidScroll call:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    SPStorkController.scrollViewDidScroll(scrollView)
}

Working with UITableView & UICollectionView

Working with a collections classes is not difficult. In the Example folder you can find an implementation. However, I will give a couple of tips for making the table look better.

Firstly, if you use SPFakeBarView, don't forget to set top insets for content & scroll indicator. Also, I recommend setting bottom insets (it optional):

tableView.contentInset.top = self.navBar.height
tableView.scrollIndicatorInsets.top = self.navBar.height

Please, also use SPStorkController.scrollViewDidScroll function in scroll delegate for more interactiveness with your collection or table view.

Confirm before dismiss

For confirm closing by swipe, tap around, close button and indicator use SPStorkControllerConfirmDelegate. Implenet protocol:

@objc public protocol SPStorkControllerConfirmDelegate: class {
    
    var needConfirm: Bool { get }
    
    func confirm(_ completion: @escaping (_ isConfirmed: Bool)->())
}

and set confirmDelegate property to object, which protocol impleneted. Function confirm call if needConfirm return true. Pass isConfirmed with result. Best options use UIAlertController with .actionSheet style for confirmation.

If you use custom buttons, in the target use this code:

SPStorkController.dismissWithConfirmation(controller: self, completion: nil)

It call confirm func and check result of confirmation. See example project for more details.

Delegate

You can check events by implement SPStorkControllerDelegate and set delegate for transitionDelegate:

transitionDelegate.storkDelegate = self

Delagate has this functions:

protocol SPStorkControllerDelegate: class {
    
    optional func didDismissStorkBySwipe()
    
    optional func didDismissStorkByTap()
}

Storyboard

If need using SPStorkController with storyboard, set class SPStorkSegue for transition setting in storyboard file. I will give the class code so that you understand what it does:

import UIKit

class SPStorkSegue: UIStoryboardSegue {
    
    public var transitioningDelegate: SPStorkTransitioningDelegate?
    
    override func perform() {
        transitioningDelegate = transitioningDelegate ?? SPStorkTransitioningDelegate()
        destination.transitioningDelegate = transitioningDelegate
        destination.modalPresentationStyle = .custom
        super.perform()
    }
}

Open your storyboard, choose transition and open right menu. Open Attributes Inspector and in Class section insert SPStorkSegue.

Modal presentation of other controller

If you want to present modal controller on SPStorkController, please set:

controller.modalPresentationStyle = .custom

It’s needed for correct presentation and dismissal of all modal controllers.

Sheets in iOS 13

Apple present in WWDC 2019 new modal presentation style - Sheets. It ready use Support interactive dismiss and work with navigations bars. Available since iOS 13. I will add more information when I study this in more detail. You can see presentation here.

Other Projects

I love being helpful. Here I have provided a list of libraries that I keep up to date. For see video previews of libraries without install open opensource.ivanvorobei.by website.
I have libraries with native interface and managing permissions. Also available pack of useful extensions for boost your development process.

Russian Community

Подписывайся в телеграмм-канал, если хочешь получать уведомления о новых туториалах.
Со сложными и непонятными задачами помогут в чате.

Видео-туториалы выклыдываю на YouTube:

Tutorials on YouTube

spstorkcontroller's People

Contributors

dstranz avatar ilia3546 avatar irskep avatar ivanvorobei avatar izyumkin avatar jobinsjohn avatar kaishin-r 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  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

spstorkcontroller's Issues

Unable to install pod

I get this error Unable to find a specification for SPStorkController when put pod install when I try to install this pod on just created project with swift 4.2 why?

App is stuck

Hello thank you so much for great plugin

 let controller = UIViewController()
        controller.transitioningDelegate = SPStorkTransitioningDelegate()
        controller.modalPresentationStyle = .custom
        present(controller, animated: true, completion: nil)

controller.transitioningDelegate = SPStorkTransitioningDelegate(): Instance will be immediately deallocated because property 'transitioningDelegate' is 'weak'

I got app stuck when using this code

thank you

Not dismissing after scroll

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    SPStorkController.scrollViewDidScroll(scrollView)
}

Adding this code does make it pan with scroll but letting go after pulling down still does not make it dismiss.

Doesn't play nice with black navigation bar(s)

Hi!
First of all thanks for this great library!
I am using cocoapods 1.4.2 and found out that the transition doesn't work right if the source controller is embedded in an navigation controller with barStyle = .black
Most of the times the transition doesn't happen and when it does, it does with significant delay. If the barStyle is default there is no problem.

custom height > possible height

Приветствую! Заметил, что при установке высоты (будь то 100, 500 или 200000) нет ограничения по максимальной высоте.

Неплохо было бы сделать проверку если customHeight больше дефолной высоты контейнера для презентации контроллера.

С Уважением, Сергей.

Presenting in NavigationController hierarchy

HI, I'm trying your pod in my project, and I can't use your presentation style on viewController, which has navigationController.

so UINavigationController -> UIViewController (configure transitionDelegate:SPStorkTransitioningDelegate and etc. like in example) -> present ModalViewController => default presentation style :(

if I try navigationController?.present(controller, animated: true, completion: nil) that also don't work
Any advice? Thank you!

Unable to Use it In Storyboards

I want to use SPStorkController in storyboard via Segues. But I am not be able to do it.
i tried this.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let vc = segue.destination
        let transitionDelegate = SPStorkTransitioningDelegate()
        vc.transitioningDelegate = transitionDelegate
        vc.modalPresentationStyle = .custom
    }

In storyborad my segue is kind of presentModally

View controller top position change after dismiss

First of all thanks a lot for this great framework!

I have multiple view controllers using SPStorkTransitioningDelegate on top of each other, but for some reason when I dismiss the child view controller the parent top position will be above the navigation bar.

Scenario:

Parent view controller first view:

File (11)

1- Going to the child view controller code:

let storyboard = UIStoryboard(name: "MyStoryBoard", bundle: nil)
        let ChildVC = storyboard.instantiateViewController(withIdentifier: "ChildVC")
        let transitionDelegate = SPStorkTransitioningDelegate()
        ContactsListVC.transitioningDelegate = transitionDelegate
        ContactsListVC.modalPresentationStyle = .custom
        present(ChildVC, animated: true, completion: nil)

2- Going back to the parent view controller

dismiss(animated: true, completion: nil)

The resulted parent view controller view:

File (13)

It's working fine on other view controllers I have, and tried to figure out the reason for this specific case but I couldn't.

Appreciate your help :)

Crash because of symbol not found

Hey there, just updated to 1.5.4 and am getting this crash when calling presentAsStork.

dyld: Symbol not found: _$SSo16UIViewControllerC07SPStorkB0E14presentAsStork_6height13showIndicator11complectionyAB_12CoreGraphics7CGFloatVSgSbyycSgtF
  Referenced from: /Users/luis/Library/Developer/CoreSimulator/Devices/DB5D83A5-6379-41FD-93C4-0CF5FE3CB65D/data/Containers/Bundle/Application/9532DAAE-57AC-4673-AE12-486AE83F7CE0/ChefBelt.app/ChefBelt
  Expected in: /Users/luis/Library/Developer/CoreSimulator/Devices/DB5D83A5-6379-41FD-93C4-0CF5FE3CB65D/data/Containers/Bundle/Application/9532DAAE-57AC-4673-AE12-486AE83F7CE0/ChefBelt.app/Frameworks/SPStorkController.framework/SPStorkController

Any ideas?

Corner Radius

I would like to change the corner radius for SPStorkController

translateForDismiss

Hello

Thanks for making this library. I do not see translateForDismiss when I try to use the library.

It's also not a public var

public var isSwipeToDismissEnabled: Bool = true
public var isTapAroundToDismissEnabled: Bool = true
public var showIndicator: Bool = true
public var indicatorColor: UIColor = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1)
public var customHeight: CGFloat? = nil

Could you tell me what I am missing?

Thanks

Adjust view controller height after turning on personal hotspot

When we present a view controller using SPStorkController then turn on personal hotspot then go back to the app, it will look like this:

IMG_0735

But if we turn on personal hotspot first, then present a view controller using SPStorkController it will look like this:

IMG_0736

Can we fix the issue in the first situation and make it look like the screenshot in the second situation?

Weird issue with UITableView

I am having a weird issue when scrolling. Cells start disappearing when you bounce the view.
From my testing is caused by SPStorkController.scrollViewDidScroll(scrollView) but not sure why yet, is this issue known?

bug

Disable swipe to dismiss in UITextView

Hello Ivan, can I disable swipe to dismiss when swiping in UITextView? I mean disable swipe to dismiss for specific view and keep it for other views in the view controller.

Present as Stork Twice

I am trying to open stork view and this view has delegate to main view. Mainview delegate triggered and I dismiss stork view. Once I try to reopen it, it does not show as stork.

Attaching my test project.

LINK TO TEST PROJECT

isSwipeToDismissEnabled does not work

Look at SPStorkPresentationController class. You use only local var isSwipeToDismissEnabled: Bool = true but isSwipeToDismissEnabled property of transitioningDelegate never used.

As a result, the code has no effect:

let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.isSwipeToDismissEnabled = false

I guess, you should fix it something like this:

if transitioningDelegate?.isSwipeToDismissEnabled ?? isSwipeToDismissEnabled { ...

custom height not taken.

I want to give custom height of pop up . previously it was happen but now after update its not found custom height .

Scrollview support

I tried the readme instructions but all I get is a message that SPStoreController cannot be found:

SPStorkController.scrollViewDidScroll(scrollView)

What am I doing wrong?

Compatibility with TableViewController

it looks like that the following method needs to be implemented to work with TableViewControllers and CollectionViewControllers:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true }

Indicator duplication

Indicator will be duplicated when controller presented many times,
can you fix this issue as soon as possible :)
Thanks.

indicator

SnapshotController

What's the correct way to delete snapshot ViewController I don't want translate effects

Compile error on SPStorkPresentationController.swift

I've added the pod (version 1.6) and when compiling the app I get a compile error in SPStorkPresentationController.swift.

The error is: Type 'CAMediaTimingFunctionName' (aka 'NSString') has no member 'easeOut'

Thank you!

SPStorkController breaks swipe gestures for UITableViewCell

When I present a UIVewController using SPStorkController it breaks swipe gestures for UITableView rows, I mean swipe to delete gesture or any swipe gesture, the delete option will not appear when you swipe unless your swipe was very very fast, if your swipe was fast then the option will appear, if your swipe was normal the option will not appear, just open your example project and add the following code to enable swipe to delete option and test it.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    }

https://github.com/IvanVorobei/SPStorkController/tree/master/Example

Indicator Position is Wrong at Navbar

Hi, thanks for this amazing pod, it will be so useful for me :)

It was easy for use, thanks for this too but I have a problem :/

When I present a viewcontroller, position of show/hide indicator at navbar is wrong. I think true position is center of navbar. You can understand what I mean with this photo :

ekran resmi 2018-12-19 04 16 30

SwipeToDismiss, the swipe down distance is too long.

Currently, when swiping/dragging from top to bottom, it is ok to dismiss the controller.

However, when I come across from AppleMusic, I found the distance needed before it can dismiss itself is a bit too long as it affects the UX.

Could you shorten or tune a bit? Or give a option to custom it?

SPStorkController dismiss delegate method

How we can identify that current Presented SPStorkController controller get dismissed.
somehow the parent controller view will appear method is not calling when dismissed the SPStorkController controller.

Thanks

Adaptive top hint bar

If the navigation bar color is in dark color, the gray line on the top of it will be not nice.

image

Could it be supported to change to white colour?

[framework] CUIThemeStore: No theme registered with id=0

I got the following errors when using tableview with SPStorkController:

2019-02-16 12:47:27.071021-0500 Test[13833:395395] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C1.1:2][0x104f1d070] get output frames failed, state 8196
2019-02-16 12:47:27.071418-0500 Test[13833:395395] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C1.1:2][0x104f1d070] get output frames failed, state 8196
2019-02-16 12:47:27.073086-0500 Test[13833:395395] TIC Read Status [1:0x0]: 1:57
2019-02-16 12:47:27.073655-0500 Test[13833:395395] TIC Read Status [1:0x0]: 1:57
2019-02-16 12:47:28.492863-0500 Test[13833:395207] [framework] CUIThemeStore: No theme registered with id=0

Need a event

hello,
I love your lib it's very easy to work with it, I need to handle when the user swipes down the model controller. could you provide some callback event when the user dismisses the model controller by swipe, kindly do needfully.

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.