Add example of changing screen at run-time
MODIFY
swift/Samples/SplitScreenContainer/DemoApp/AppDelegate.swift
swift/Samples/SplitScreenContainer/DemoApp/AppDelegate.swift
@@ -29,7 +29,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var viewRegistry = ViewRegistry()
viewRegistry.registerSplitScreenContainer()
- viewRegistry.registerBaseScreen()
+ viewRegistry.registerFooScreen()
+ viewRegistry.registerBarScreen()
let container = ContainerViewController(
workflow: DemoWorkflow(),
@@ -47,7 +48,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
extension ViewRegistry {
public mutating func registerSplitScreenContainer() {
- self.register(screenViewControllerType: SplitScreenContainerViewController<AnyScreen, BaseScreen>.self)
+ self.register(screenViewControllerType: SplitScreenContainerViewController<AnyScreen, FooScreen>.self)
}
}

ADD
swift/Samples/SplitScreenContainer/DemoApp/BarScreen.swift
+/*
+ * Copyright 2019 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import Workflow
+import WorkflowUI
+
+
+struct BarScreen: Screen {
+ let title: String
+ let backgroundColors: [UIColor]
+ let viewTapped: () -> Void
+}
+
+
+extension ViewRegistry {
+
+ public mutating func registerBarScreen() {
+ self.register(screenViewControllerType: BarScreenViewController.self)
+ }
+
+}
+
+
+fileprivate final class BarScreenViewController: ScreenViewController<BarScreen> {
+
+ private lazy var titleLabel: UILabel = .init()
+ private lazy var tapGestureRecognizer: UITapGestureRecognizer = .init()
+ private var gradientLayer: CAGradientLayer?
+
+ required init(screen: BarScreen, viewRegistry: ViewRegistry) {
+ super.init(screen: screen, viewRegistry: viewRegistry)
+
+ update(with: screen)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ tapGestureRecognizer.addTarget(self, action: #selector(viewTapped))
+ view.addGestureRecognizer(tapGestureRecognizer)
+
+ titleLabel.translatesAutoresizingMaskIntoConstraints = false
+ titleLabel.textAlignment = .center
+ titleLabel.textColor = .white
+ view.addSubview(titleLabel)
+
+ NSLayoutConstraint.activate([
+ titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
+ titleLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
+ ])
+
+ updateGradient(for: view, colors: screen.backgroundColors)
+ }
+
+ override func screenDidChange(from previousScreen: BarScreen) {
+ update(with: screen)
+ }
+
+ private func update(with screen: BarScreen) {
+ titleLabel.text = screen.title
+
+ updateGradient(for: view, colors: screen.backgroundColors)
+ }
+
+ private func updateGradient(for targetView: UIView, colors: [UIColor]) {
+ let newGradientLayer = CAGradientLayer()
+
+ newGradientLayer.frame = targetView.bounds
+ newGradientLayer.colors = colors.map({ $0.cgColor })
+
+ targetView.layer.insertSublayer(newGradientLayer, at: 0)
+
+ gradientLayer?.removeFromSuperlayer()
+
+ gradientLayer = newGradientLayer
+ }
+
+ @objc
+ private func viewTapped() {
+ screen.viewTapped()
+ }
+}
+

MODIFY
swift/Samples/SplitScreenContainer/DemoApp/DemoWorkflow.swift
swift/Samples/SplitScreenContainer/DemoApp/DemoWorkflow.swift
@@ -66,19 +66,48 @@ extension DemoWorkflow {
extension DemoWorkflow {
- typealias Rendering = SplitScreenContainerScreen<AnyScreen, BaseScreen>
+ typealias Rendering = SplitScreenContainerScreen<AnyScreen, FooScreen>
private static let sizes: [CGFloat] = [.quarter, .third, .half, 0.75]
+ private static let colors: [UIColor] = [.red, .blue, .green, .yellow]
+ private static let complimentaryColors: [UIColor] = [.blue, .green, .yellow, .purple,]
func render(state: State, context: RenderContext<DemoWorkflow>) -> Rendering {
let sink = context.makeSink(of: Action.self)
return SplitScreenContainerScreen(
- leftScreen: AnyScreen(BaseScreen(title: "Left screen", backgroundColor: .red, viewTapped: { sink.send(.viewTapped) })),
- rightScreen: BaseScreen(title: "Right screen", backgroundColor: .green, viewTapped: { sink.send(.viewTapped) }),
+ leftScreen: leftScreenFor(state: state, context: context),
+ rightScreen: FooScreen(title: "Right screen", backgroundColor: .green, viewTapped: { sink.send(.viewTapped) }),
ratio: DemoWorkflow.sizes[state % DemoWorkflow.sizes.count]
)
}
+ private func leftScreenFor(state: State, context: RenderContext<DemoWorkflow>) -> AnyScreen {
+ let sink = context.makeSink(of: Action.self)
+
+ let color = DemoWorkflow.colors[state % DemoWorkflow.colors.count]
+
+ if state % 2 == 0 {
+ return AnyScreen(
+ FooScreen(
+ title: "Left Foo screen",
+ backgroundColor: color,
+ viewTapped: { sink.send(.viewTapped) }
+ )
+ )
+ } else {
+ let complimentaryColor = DemoWorkflow.complimentaryColors[state % DemoWorkflow.complimentaryColors.count]
+
+ return AnyScreen(
+ BarScreen(
+ title: "Left Bar screen",
+ backgroundColors: [color, complimentaryColor],
+ viewTapped: { sink.send(.viewTapped) }
+ )
+ )
+ }
+
+ }
+
}

RENAME
swift/Samples/SplitScreenContainer/DemoApp/BaseScreen.swift
swift/Samples/SplitScreenContainer/DemoApp/FooScreen.swift
@@ -17,7 +17,7 @@ import Workflow
import WorkflowUI
-struct BaseScreen: Screen {
+struct FooScreen: Screen {
let title: String
let backgroundColor: UIColor
let viewTapped: () -> Void
@@ -26,19 +26,19 @@ struct BaseScreen: Screen {
extension ViewRegistry {
- public mutating func registerBaseScreen() {
- self.register(screenViewControllerType: BaseScreenViewController.self)
+ public mutating func registerFooScreen() {
+ self.register(screenViewControllerType: FooScreenViewController.self)
}
}
-fileprivate final class BaseScreenViewController: ScreenViewController<BaseScreen> {
+fileprivate final class FooScreenViewController: ScreenViewController<FooScreen> {
private lazy var titleLabel: UILabel = .init()
private lazy var tapGestureRecognizer: UITapGestureRecognizer = .init()
- required init(screen: BaseScreen, viewRegistry: ViewRegistry) {
+ required init(screen: FooScreen, viewRegistry: ViewRegistry) {
super.init(screen: screen, viewRegistry: viewRegistry)
update(with: screen)
@@ -60,11 +60,11 @@ fileprivate final class BaseScreenViewController: ScreenViewController<BaseScree
])
}
- override func screenDidChange(from previousScreen: BaseScreen) {
+ override func screenDidChange(from previousScreen: FooScreen) {
update(with: screen)
}
- private func update(with screen: BaseScreen) {
+ private func update(with screen: FooScreen) {
view.backgroundColor = screen.backgroundColor
titleLabel.text = screen.title
}

Add example of changing screen at run-time