Toast mounts to UIWindow (#603)

This commit is contained in:
Ryan Nystrom
2017-10-18 16:33:44 -04:00
committed by GitHub
parent 244e73106c
commit 72429dbaea
4 changed files with 31 additions and 34 deletions

View File

@@ -140,7 +140,7 @@ final class NewIssueTableViewController: UITableViewController, UITextFieldDeleg
strongSelf.setRightBarItemIdle()
guard let model = model else {
ToastManager.showGenericError(viewController: self)
ToastManager.showGenericError()
return
}

View File

@@ -10,8 +10,8 @@ import Foundation
extension ToastManager {
private static var rootViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController
private static var window: UIView? {
return UIApplication.shared.keyWindow
}
private static func provideHapticFeedback() {
@@ -34,28 +34,28 @@ extension ToastManager {
)
}
static func showRevokeError(viewController: UIViewController? = rootViewController) {
ToastManager.shared.show(viewController: viewController, config: errorConfig(text: NSLocalizedString("Your access token was revoked.", comment: "")))
static func showRevokeError(view: UIView? = window) {
ToastManager.shared.show(in: view, config: errorConfig(text: NSLocalizedString("Your access token was revoked.", comment: "")))
provideHapticFeedback()
}
static func showNetworkError(viewController: UIViewController? = rootViewController) {
ToastManager.shared.show(viewController: viewController, config: errorConfig(text: NSLocalizedString("Cannot connect to GitHub.", comment: "")))
static func showNetworkError(view: UIView? = window) {
ToastManager.shared.show(in: view, config: errorConfig(text: NSLocalizedString("Cannot connect to GitHub.", comment: "")))
provideHapticFeedback()
}
static func showGenericError(viewController: UIViewController? = rootViewController) {
ToastManager.shared.show(viewController: viewController, config: errorConfig(text: NSLocalizedString("Something went wrong.", comment: "")))
static func showGenericError(view: UIView? = window) {
ToastManager.shared.show(in: view, config: errorConfig(text: NSLocalizedString("Something went wrong.", comment: "")))
provideHapticFeedback()
}
static func showPermissionsError(viewController: UIViewController? = rootViewController) {
ToastManager.shared.show(viewController: viewController, config: errorConfig(text: NSLocalizedString("You must request access.", comment: "")))
static func showPermissionsError(view: UIView? = window) {
ToastManager.shared.show(in: view, config: errorConfig(text: NSLocalizedString("You must request access.", comment: "")))
provideHapticFeedback()
}
static func showError(message: String, viewController: UIViewController? = rootViewController) {
ToastManager.shared.show(viewController: viewController, config: errorConfig(text: message))
static func showError(message: String, view: UIView? = window) {
ToastManager.shared.show(in: view, config: errorConfig(text: message))
provideHapticFeedback()
}

View File

@@ -174,14 +174,10 @@ private func rubberBandDistance(offset: CGFloat, dimension: CGFloat) -> CGFloat
return offset < 0 ? -result : result
}
private func anchor(view: UIView, viewController: UIViewController?) -> CGPoint {
guard let viewController = viewController,
let referenceView = viewController.view
else { return .zero }
private func anchor(view: UIView, referenceView: UIView) -> CGPoint {
let safeBottom: CGFloat
if #available(iOS 11.0, *) {
safeBottom = referenceView.safeAreaInsets.bottom + viewController.additionalSafeAreaInsets.bottom
safeBottom = referenceView.safeAreaInsets.bottom
} else {
safeBottom = 0
}
@@ -201,28 +197,24 @@ final class ToastManager {
let animator: UIDynamicAnimator
let springBehavior: UIAttachmentBehavior
let configuration: ToastViewConfiguration
private weak var viewController: UIViewController? = nil
private var timer: Timer? = nil
init?(config: ToastViewConfiguration, viewController: UIViewController) {
guard let referenceView = viewController.view else { return nil }
self.viewController = viewController
init?(config: ToastViewConfiguration, in baseView: UIView) {
configuration = config
view = ToastView(configuration: config)
view.frame = CGRect(origin: .zero, size: view.contentSize())
referenceView.addSubview(view)
baseView.addSubview(view)
animator = UIDynamicAnimator(referenceView: referenceView)
animator = UIDynamicAnimator(referenceView: baseView)
let initAnchor = anchor(view: view, viewController: viewController)
let initAnchor = anchor(view: view, referenceView: baseView)
// position off screen so it snaps in. must happen before setting up spring
view.center = initAnchor.applying(CGAffineTransform(
translationX: 0,
y: referenceView.bounds.height - initAnchor.y + 500
y: baseView.bounds.height - initAnchor.y + 500
))
springBehavior = UIAttachmentBehavior(item: view, attachedToAnchor: initAnchor)
@@ -263,10 +255,13 @@ final class ToastManager {
func recenter() {
// UIDynamics will throw if adding the behavior back when the view has already been removed
guard view.superview != nil else { return }
guard view.superview != nil,
let referenceView = animator.referenceView
else { return }
// hack to work around UI bug where behavior will permanently oscillate
animator.removeBehavior(springBehavior)
springBehavior.anchorPoint = anchor(view: view, viewController: viewController)
springBehavior.anchorPoint = anchor(view: view, referenceView: referenceView)
animator.addBehavior(springBehavior)
}
@@ -298,15 +293,15 @@ final class ToastManager {
public static let shared = ToastManager()
public func show(
viewController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController,
in view: UIView? = UIApplication.shared.keyWindow,
config: ToastViewConfiguration
) {
guard let viewController = viewController else { return }
guard let baseView = view else { return }
// get rid of any view if currently displaying
toast?.dismiss()
toast = Toast(config: config, viewController: viewController)
toast = Toast(config: config, in: baseView)
toast?.view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(ToastManager.onPan(gesture:))))
toast?.startTimer()
}
@@ -367,3 +362,5 @@ final class ToastManager {
}
}

View File

@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>2110</string>
<string>2111</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>