Commit 9fa456da by Daniel Dahan

updated fromView and toView in MotionController to no longer use unwrapped optionals

parent 430cc140
......@@ -207,13 +207,13 @@ public class Motion: MotionController {
}
/// A reference to the fromView, fromViewController.view.
internal var fromView: UIView {
return fromViewController!.view
internal var fromView: UIView? {
return fromViewController?.view
}
/// A reference to the toView, toViewController.view.
internal var toView: UIView {
return toViewController!.view
internal var toView: UIView? {
return toViewController?.view
}
/// An initializer.
......@@ -267,7 +267,11 @@ fileprivate extension Motion {
internal extension Motion {
override func animate() {
context.unhide(view: toView)
guard let tv = toView else {
return
}
context.unhide(view: tv)
updateContainerBackgroundColor()
updateInsertOrder()
......@@ -290,27 +294,34 @@ internal extension Motion {
return
}
guard let fv = fromView else {
return
}
guard let tv = toView else {
return
}
context.clean()
if isFinished && isPresenting && toOverFullScreen {
// finished presenting a overFullScreen VC
context.unhide(rootView: toView)
context.removeSnapshots(rootView: toView)
context.storeViewAlpha(rootView: fromView)
context.unhide(rootView: tv)
context.removeSnapshots(rootView: tv)
context.storeViewAlpha(rootView: fv)
fromViewController!.motionStoredSnapshot = container
fromView.removeFromSuperview()
fromView.addSubview(c)
fv.removeFromSuperview()
fv.addSubview(c)
} else if !isFinished && !isPresenting && fromOverFullScreen {
// cancelled dismissing a overFullScreen VC
context.unhide(rootView: fromView)
context.removeSnapshots(rootView: fromView)
context.storeViewAlpha(rootView: toView)
context.unhide(rootView: fv)
context.removeSnapshots(rootView: fv)
context.storeViewAlpha(rootView: tv)
toViewController!.motionStoredSnapshot = container
toView.removeFromSuperview()
toView.addSubview(c)
tv.removeFromSuperview()
tv.addSubview(c)
} else {
context.unhideAll()
context.removeAllSnapshots()
......@@ -319,15 +330,15 @@ internal extension Motion {
// move fromView & toView back from our container back to the one supplied by UIKit
if (toOverFullScreen && isFinished) || (fromOverFullScreen && !isFinished) {
tc.addSubview(isFinished ? fromView : toView)
tc.addSubview(isFinished ? fv : tv)
}
tc.addSubview(isFinished ? toView : fromView)
tc.addSubview(isFinished ? tv : fv)
if isPresenting != isFinished, !isContainerController {
// only happens when present a .overFullScreen VC
// bug: http://openradar.appspot.com/radar?id=5320103646199808
UIApplication.shared.keyWindow!.addSubview(isPresenting ? fromView : toView)
UIApplication.shared.keyWindow!.addSubview(isPresenting ? fv : tv)
}
// use temp variables to remember these values
......@@ -378,7 +389,7 @@ fileprivate extension Motion {
return
}
fullScreenSnapshot = v.window?.snapshotView(afterScreenUpdates: true) ?? fromView.snapshotView(afterScreenUpdates: true)
fullScreenSnapshot = v.window?.snapshotView(afterScreenUpdates: true) ?? fromView?.snapshotView(afterScreenUpdates: true)
(v.window ?? transitionContainer)?.addSubview(fullScreenSnapshot)
if let v = fromViewController?.motionStoredSnapshot {
......@@ -398,23 +409,47 @@ fileprivate extension Motion {
return
}
context.loadViewAlpha(rootView: toView)
context.loadViewAlpha(rootView: fromView)
v.addSubview(toView)
v.addSubview(fromView)
guard let fv = fromView else {
return
}
guard let tv = toView else {
return
}
context.loadViewAlpha(rootView: tv)
context.loadViewAlpha(rootView: fv)
v.addSubview(tv)
v.addSubview(fv)
}
/// Prepares the toView instance.
func prepareToView() {
toView.frame = fromView.frame
toView.updateConstraints()
toView.setNeedsLayout()
toView.layoutIfNeeded()
guard let fv = fromView else {
return
}
guard let tv = toView else {
return
}
tv.frame = fv.frame
tv.updateConstraints()
tv.setNeedsLayout()
tv.layoutIfNeeded()
}
/// Prepares the view hierarchy.
func prepareViewHierarchy() {
context.set(fromViews: fromView.flattenedViewHierarchy, toViews: toView.flattenedViewHierarchy)
guard let fv = fromView else {
return
}
guard let tv = toView else {
return
}
context.set(fromViews: fv.flattenedViewHierarchy, toViews: tv.flattenedViewHierarchy)
}
}
......@@ -426,7 +461,12 @@ internal extension Motion {
override func prepareTransitionPairs() {
super.prepareTransitionPairs()
context.hide(view: toView)
guard let tv = toView else {
return
}
context.hide(view: tv)
}
}
......@@ -560,7 +600,7 @@ fileprivate extension Motion {
if let v = containerBackgroundColor {
container?.backgroundColor = v
} else if !toOverFullScreen && !fromOverFullScreen {
container?.backgroundColor = toView.backgroundColor
container?.backgroundColor = toView?.backgroundColor
}
}
......
......@@ -197,6 +197,14 @@ class TransitionPreprocessor: MotionPreprocessor {
return
}
guard let fv = m.fromView else {
return
}
guard let tv = m.toView else {
return
}
var defaultAnimation = m.defaultAnimation
let isNavigationController = m.isNavigationController
let isTabBarController = m.isTabBarController
......@@ -205,8 +213,6 @@ class TransitionPreprocessor: MotionPreprocessor {
let isPresenting = m.isPresenting
let fromOverFullScreen = m.fromOverFullScreen
let toOverFullScreen = m.toOverFullScreen
let toView = m.toView
let fromView = m.fromView
let animators = m.animators
if case .auto = defaultAnimation {
......@@ -226,7 +232,7 @@ class TransitionPreprocessor: MotionPreprocessor {
}
if case .auto = defaultAnimation {
if animators!.contains(where: { $0.canAnimate(view: toView, isAppearing: true) || $0.canAnimate(view: fromView, isAppearing: false) }) {
if animators!.contains(where: { $0.canAnimate(view: tv, isAppearing: true) || $0.canAnimate(view: fv, isAppearing: false) }) {
defaultAnimation = .none
} else if isNavigationController {
......@@ -244,8 +250,8 @@ class TransitionPreprocessor: MotionPreprocessor {
return
}
context[fromView] = [.timingFunction(.standard), .duration(0.35)]
context[toView] = [.timingFunction(.standard), .duration(0.35)]
context[fv] = [.timingFunction(.standard), .duration(0.35)]
context[tv] = [.timingFunction(.standard), .duration(0.35)]
let shadowState: [MotionTransition] = [.shadow(opacity: 0.5),
.shadow(color: .black),
......@@ -255,93 +261,93 @@ class TransitionPreprocessor: MotionPreprocessor {
switch defaultAnimation {
case .push(let direction):
context[toView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)),
context[tv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)),
.shadow(opacity: 0),
.beginWith(transitions: shadowState),
.timingFunction(.deceleration)])
context[fromView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false) / 3),
context[fv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false) / 3),
.overlay(color: .black, opacity: 0.1),
.timingFunction(.deceleration)])
case .pull(let direction):
m.insertToViewFirst = true
context[fromView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)),
context[fv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)),
.shadow(opacity: 0),
.beginWith(transitions: shadowState)])
context[toView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true) / 3),
context[tv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true) / 3),
.overlay(color: .black, opacity: 0.1)])
case .slide(let direction):
context[fromView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false))])
context[fv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false))])
context[toView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true))])
context[tv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true))])
case .zoomSlide(let direction):
context[fromView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)), .scale(to: 0.8)])
context[fv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)), .scale(to: 0.8)])
context[toView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)), .scale(to: 0.8)])
context[tv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)), .scale(to: 0.8)])
case .cover(let direction):
context[toView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)),
context[tv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)),
.shadow(opacity: 0),
.beginWith(transitions: shadowState),
.timingFunction(.deceleration)])
context[fromView]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1),
context[fv]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1),
.timingFunction(.deceleration)])
case .uncover(let direction):
m.insertToViewFirst = true
context[fromView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)),
context[fv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)),
.shadow(opacity: 0),
.beginWith(transitions: shadowState)])
context[toView]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1)])
context[tv]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1)])
case .pageIn(let direction):
context[toView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)),
context[tv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: true)),
.shadow(opacity: 0),
.beginWith(transitions: shadowState),
.timingFunction(.deceleration)])
context[fromView]!.append(contentsOf: [.scale(to: 0.7),
context[fv]!.append(contentsOf: [.scale(to: 0.7),
.overlay(color: .black, opacity: 0.1),
.timingFunction(.deceleration)])
case .pageOut(let direction):
m.insertToViewFirst = true
context[fromView]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)),
context[fv]!.append(contentsOf: [.translate(to: shift(direction: direction, isAppearing: false)),
.shadow(opacity: 0),
.beginWith(transitions: shadowState)])
context[toView]!.append(contentsOf: [.scale(to: 0.7),
context[tv]!.append(contentsOf: [.scale(to: 0.7),
.overlay(color: .black, opacity: 0.1)])
case .fade:
// TODO: clean up this. overFullScreen logic shouldn't be here
if !(fromOverFullScreen && !isPresenting) {
context[toView] = [.fade]
context[tv] = [.fade]
}
#if os(tvOS)
context[fromView] = [.fade]
#else
if (!isPresenting && toOverFullScreen) || !fromView.isOpaque || (fromView.backgroundColor?.alphaComponent ?? 1) < 1 {
context[fromView] = [.fade]
if (!isPresenting && toOverFullScreen) || !fv.isOpaque || (fv.backgroundColor?.alphaComponent ?? 1) < 1 {
context[fv] = [.fade]
}
#endif
context[toView]!.append(.preferredDurationMatchesLongest)
context[fromView]!.append(.preferredDurationMatchesLongest)
context[tv]!.append(.preferredDurationMatchesLongest)
context[fv]!.append(.preferredDurationMatchesLongest)
case .zoom:
m.insertToViewFirst = true
context[fromView]!.append(contentsOf: [.scale(to: 1.3), .fade])
context[toView]!.append(contentsOf: [.scale(to: 0.7)])
context[fv]!.append(contentsOf: [.scale(to: 1.3), .fade])
context[tv]!.append(contentsOf: [.scale(to: 0.7)])
case .zoomOut:
context[toView]!.append(contentsOf: [.scale(to: 1.3), .fade])
context[fromView]!.append(contentsOf: [.scale(to: 0.7)])
context[tv]!.append(contentsOf: [.scale(to: 1.3), .fade])
context[fv]!.append(contentsOf: [.scale(to: 0.7)])
default:
fatalError("Not implemented")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment