source/UberRides/ModalViewController.swift (98 lines of code) (raw):
//
// ModalViewController.swift
// UberRides
//
// Copyright © 2015 Uber Technologies, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import UberCore
/**
Possible Styles for the ModalViewController
- Empty: Presents the view modally without any BarButtonItems
- DoneButton: Presents the view mdoally with a Done BarButtonItem in the top right corner
- Warning: The Ride Request Widget is deprecated, and will no longer work for new apps.
Existing apps have until 05/31/2018 to migrate. See the Uber API Changelog for more details.
*/
@objc public enum ModalViewControllerButtonStyle : Int {
case empty
case doneButton
case backButton
}
/**
Possible color style for the ModalViewController
- Default: Default dark style, dark navigation bar with light text
- Light: Light color style, light navigation bar with dark text
- Warning: The Ride Request Widget is deprecated, and will no longer work for new apps.
Existing apps have until 05/31/2018 to migrate. See the Uber API Changelog for more details.
*/
@objc public enum ModalViewControllerColorStyle : Int {
case `default`
case light
}
/**
* The ModalViewControllerDelegate protocol
- Warning: The Ride Request Widget is deprecated, and will no longer work for new apps.
Existing apps have until 05/31/2018 to migrate. See the Uber API Changelog for more details.
*/
@objc(UBSDKModalViewControllerDelegate) public protocol ModalViewControllerDelegate {
/**
Called before the ModalViewController dismisses the modal.
- parameter modalViewController: The ModalViewController that will be dismissed
*/
@objc func modalViewControllerWillDismiss(_ modalViewController: ModalViewController)
/**
Called after the ModalViewController is dismissed.
- parameter modalViewController: The ModalViewController that was dismissed
*/
@objc func modalViewControllerDidDismiss(_ modalViewController: ModalViewController)
}
/**
Convenience to wrap a ViewController in a UINavigationController and add the appropriate buttons. Allows you to modally present a view controller w/ Uber branding.
- Warning: The Ride Request Widget is deprecated, and will no longer work for new apps.
Existing apps have until 05/31/2018 to migrate. See the Uber API Changelog for more details.
*/
@objc(UBSDKModalViewController) public class ModalViewController : UIViewController {
/// The ModalViewControllerDelegate
@objc public var delegate: ModalViewControllerDelegate?
@objc public var colorStyle: ModalViewControllerColorStyle = .default {
didSet {
setupStyle()
}
}
var buttonStyle: ModalViewControllerButtonStyle
var wrappedViewController: UIViewController
var wrappedNavigationController: UINavigationController
//MARK: Initializers
/**
Initializes a ModalViewController for the given childViewController and style inside a UINavigationController
with the appropriate buttons.
- parameter childViewController: The child UIViewController to wrap
- parameter buttonStyle: The ModalViewControllerButtonStyle to use
- returns: An initialized ModalViewController
*/
@objc public init(childViewController: UIViewController, buttonStyle: ModalViewControllerButtonStyle) {
wrappedViewController = childViewController
wrappedNavigationController = UINavigationController(rootViewController: childViewController)
self.buttonStyle = buttonStyle
super.init(nibName: nil, bundle: nil)
setupStyle()
}
/**
Initializes a ModalViewController for the given childViewController and style inside a UINavigationController
with the appropriate buttons.
Defaults to the .DoneButton ModalViewControllerButtonStyle style
- parameter childViewController: The child UIViewController to wrap
- returns: An initialized ModalViewController
*/
@objc public convenience init(childViewController: UIViewController) {
self.init(childViewController: childViewController, buttonStyle: .doneButton)
}
/**
Unavailable. ModalViewController doesn't support being initialized via
init(coder:)
- throws: Fatal Error
*/
@objc required public init?(coder aDecoder: NSCoder) {
fatalError("ModalViewController doesn't support init(coder:)")
}
//MARK: View Lifecycle
public override func viewDidLoad() {
super.viewDidLoad()
self.addChild(wrappedNavigationController)
self.view.addSubview(self.wrappedNavigationController.view)
self.wrappedNavigationController.didMove(toParent: self)
}
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.delegate?.modalViewControllerDidDismiss(self)
}
//MARK: Public
/**
Function to dimiss the modalViewController.
*/
@objc public func dismiss() {
self.delegate?.modalViewControllerWillDismiss(self)
self.dismiss(animated: true, completion: nil)
}
public override var preferredStatusBarStyle : UIStatusBarStyle {
switch colorStyle {
case .light:
return UIStatusBarStyle.default
case .default:
return UIStatusBarStyle.lightContent
}
}
//MARK: Button Actions
@objc func doneButtonPressed(_ button: UIButton) {
dismiss()
}
@objc func backButtonPressed(_ button: UIButton) {
dismiss()
}
//MARK: Private Helpers
private func setupStyle() {
let coreBundle = Bundle(for: UberAppDelegate.self)
let bundle = Bundle(for: RideRequestButton.self)
self.wrappedViewController.navigationItem.leftBarButtonItem = nil
self.wrappedViewController.navigationItem.rightBarButtonItem = nil
var iconTintColor = UIColor.white
switch colorStyle {
case .light:
iconTintColor = UIColor.black
wrappedViewController.navigationController?.navigationBar.barStyle = .default
case .default:
wrappedViewController.navigationController?.navigationBar.barStyle = .black
break
}
switch buttonStyle {
case .empty:
break
case .doneButton:
let doneButton = UIBarButtonItem(barButtonSystemItem: .done , target: self, action: #selector(doneButtonPressed(_:)))
doneButton.tintColor = iconTintColor
self.wrappedViewController.navigationItem.rightBarButtonItem = doneButton
case .backButton:
let backImage = UIImage(named: "ic_back_arrow_white", in: bundle, compatibleWith: nil)
let backButton = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(backButtonPressed(_:)))
backButton.tintColor = iconTintColor
self.wrappedViewController.navigationItem.leftBarButtonItem = backButton
}
let logoImage = UIImage(named: "ic_logo_white", in: coreBundle, compatibleWith: nil)?.withRenderingMode(.alwaysTemplate)
let logoImageView = UIImageView(image: logoImage)
logoImageView.tintColor = iconTintColor
wrappedViewController.navigationItem.titleView = logoImageView
}
}