diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example-iOS/RiveExample.xcodeproj/project.pbxproj b/Example-iOS/RiveExample.xcodeproj/project.pbxproj index d339d54..afbf58f 100644 --- a/Example-iOS/RiveExample.xcodeproj/project.pbxproj +++ b/Example-iOS/RiveExample.xcodeproj/project.pbxproj @@ -48,6 +48,8 @@ C324DB5B2807216B0060589F /* RiveSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C324DB5A2807216B0060589F /* RiveSlider.swift */; }; C324DB5D280728690060589F /* RiveButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C324DB5C280728690060589F /* RiveButton.swift */; }; C324DB5F280740FB0060589F /* rbutton.riv in Resources */ = {isa = PBXBuildFile; fileRef = C324DB5E280740FB0060589F /* rbutton.riv */; }; + C3357CA1280F42EC00F03B6F /* ExamplesMaster.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3357CA0280F42EC00F03B6F /* ExamplesMaster.swift */; }; + C3357CA5280F430000F03B6F /* ExamplesDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3357CA4280F430000F03B6F /* ExamplesDetail.swift */; }; C3460A002800A6CE002DBCB7 /* bird.riv in Resources */ = {isa = PBXBuildFile; fileRef = C34609FD2800A6CE002DBCB7 /* bird.riv */; }; C3468E6227FDCBC6008652FD /* SimpleSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3468E6127FDCBC6008652FD /* SimpleSlider.swift */; }; C3D187F3280751A8008B739A /* RiveProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D187F2280751A8008B739A /* RiveProgressBar.swift */; }; @@ -141,6 +143,8 @@ C324DB5A2807216B0060589F /* RiveSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveSlider.swift; sourceTree = ""; }; C324DB5C280728690060589F /* RiveButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveButton.swift; sourceTree = ""; }; C324DB5E280740FB0060589F /* rbutton.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = rbutton.riv; sourceTree = ""; }; + C3357CA0280F42EC00F03B6F /* ExamplesMaster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExamplesMaster.swift; sourceTree = ""; }; + C3357CA4280F430000F03B6F /* ExamplesDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExamplesDetail.swift; sourceTree = ""; }; C34609FD2800A6CE002DBCB7 /* bird.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = bird.riv; sourceTree = ""; }; C3468E6127FDCBC6008652FD /* SimpleSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleSlider.swift; sourceTree = ""; }; C3D187F2280751A8008B739A /* RiveProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveProgressBar.swift; sourceTree = ""; }; @@ -294,16 +298,18 @@ C9C73E9624FC471E00EF9516 /* Source */ = { isa = PBXGroup; children = ( - 04A8F6C226452F25002C909A /* lib */, C324DB592807202A0060589F /* Widgets */, C9A84F342644931E0014D8E0 /* SwiftUI */, 042C88862643DB2200E7DBB2 /* UIkit */, - C9C73E9724FC471E00EF9516 /* AppDelegate.swift */, - C9C73E9924FC471E00EF9516 /* SceneDelegate.swift */, - C9C73EA524FC471E00EF9516 /* Info.plist */, + 042C88822643D6B900E7DBB2 /* Main.storyboard */, + C3357CA0280F42EC00F03B6F /* ExamplesMaster.swift */, + C3357CA4280F430000F03B6F /* ExamplesDetail.swift */, C9C73E9D24FC471E00EF9516 /* Assets.xcassets */, C9C73E9F24FC471E00EF9516 /* Preview Content */, - 042C88822643D6B900E7DBB2 /* Main.storyboard */, + 04A8F6C226452F25002C909A /* lib */, + C9C73E9924FC471E00EF9516 /* SceneDelegate.swift */, + C9C73E9724FC471E00EF9516 /* AppDelegate.swift */, + C9C73EA524FC471E00EF9516 /* Info.plist */, ); path = Source; sourceTree = ""; @@ -458,9 +464,11 @@ C9CB2F13264C92D200E7FF0D /* RiveComponents.swift in Sources */, 042C888E2644230700E7DBB2 /* utility.swift in Sources */, C3D187F3280751A8008B739A /* RiveProgressBar.swift in Sources */, + C3357CA5280F430000F03B6F /* ExamplesDetail.swift in Sources */, E5CD7D7127DC331900BFE5E2 /* SwiftMeshAnimation.swift in Sources */, 042C88902644250D00E7DBB2 /* MultipleAnimations.swift in Sources */, C3468E6227FDCBC6008652FD /* SimpleSlider.swift in Sources */, + C3357CA1280F42EC00F03B6F /* ExamplesMaster.swift in Sources */, C324DB5628071EB80060589F /* RiveSwitch.swift in Sources */, 04026DC827CE3EE6002B3DBF /* SwiftLayout.swift in Sources */, 04026DCC27CE3F03002B3DBF /* SwiftLoopMode.swift in Sources */, diff --git a/Example-iOS/Source/ExamplesMaster.swift b/Example-iOS/Source/ExamplesMaster.swift new file mode 100644 index 0000000..bd64578 --- /dev/null +++ b/Example-iOS/Source/ExamplesMaster.swift @@ -0,0 +1,113 @@ +// +// ExamplesMaster.swift +// RiveExample +// +// Created by Zachary Duncan on 4/19/22. +// Copyright © 2022 Rive. All rights reserved. +// + +import SwiftUI +import RiveRuntime + +class ExamplesMasterTableViewController: UITableViewController { + private let storyboardIDs: [String] = [ + "Simple Animation", + "Layout", + "MultipleAnimations", + "Loop Mode", + "State Machine", +// "iOS Player", + "Blend Mode", + "Slider Widget" + ] + + private enum SwiftViews: StringLiteralType, CaseIterable { + case components = "Widget Collection" + case simpleAnimation = "Simple Animation" + case layout = "Layout" + case multiple = "MultipleAnimations" + case loop = "Loop Mode" + case stateMachine = "State Machine" + case mesh = "Mesh Animation" + } + + private let viewModels: [(String, RiveViewModel)] = [ + ("Slider Widget", RiveSlider()) + ] + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return storyboardIDs.count + SwiftViews.allCases.count + viewModels.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let i = indexPath.row + let cell = UITableViewCell() + + // ViewControllers made from Storyboard IDs + if i < storyboardIDs.count { + cell.textLabel?.text = storyboardIDs[indexPath.row] + } + + // Views made by custom SwiftUI Views + else if i < storyboardIDs.count + SwiftViews.allCases.count { + cell.textLabel?.text = SwiftViews.allCases[i - storyboardIDs.count].rawValue + } + + // Views made by the ViewModels + else { + cell.textLabel?.text = viewModels[i - (storyboardIDs.count + SwiftViews.allCases.count)].0 + } + + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let i = indexPath.row + var controller: UIViewController + + // ViewControllers made from Storyboard IDs + if i < storyboardIDs.count { + controller = storyboard!.instantiateViewController(withIdentifier: storyboardIDs[i]) + } + + // Views made by custom SwiftUI Views + else if i < storyboardIDs.count + SwiftViews.allCases.count { + var anyView: AnyView + + switch SwiftViews.allCases[i - storyboardIDs.count] { + case .components: anyView = typeErased(dismissableView: RiveComponents()) + case .simpleAnimation: anyView = typeErased(dismissableView: SwiftSimpleAnimation()) + case .layout: anyView = typeErased(dismissableView: SwiftLayout()) + case .multiple: anyView = typeErased(dismissableView: SwiftMultipleAnimations()) + case .loop: anyView = typeErased(dismissableView: SwiftLoopMode()) + case .stateMachine: anyView = typeErased(dismissableView: SwiftStateMachine()) + case .mesh: anyView = typeErased(dismissableView: SwiftMeshAnimation()) + } + + controller = UIHostingController(rootView: anyView) + } + + // Views made by the ViewModels + else { + let anyView = AnyView(viewModels[i - (storyboardIDs.count + SwiftViews.allCases.count)].1.view()) + controller = UIHostingController(rootView: anyView) + } + + splitViewController?.showDetailViewController(controller, sender: self) + } + + private func typeErased(dismissableView: Content) -> AnyView { + var view = dismissableView + view.dismiss = { + self.dismiss(animated: true, completion: nil) + self.navigationController?.popViewController(animated: true) + } + + return AnyView(view) + } +} + +public protocol DismissableView: View { + init() + var dismiss: () -> Void { get set } +} diff --git a/Example-iOS/Source/Main.storyboard b/Example-iOS/Source/Main.storyboard index 5993e60..cdddf85 100644 --- a/Example-iOS/Source/Main.storyboard +++ b/Example-iOS/Source/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -9,6 +9,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -168,12 +237,12 @@ - + - + @@ -199,12 +268,12 @@ - + - + @@ -393,12 +462,12 @@ - + - + @@ -409,12 +478,12 @@ - + - + @@ -637,12 +706,12 @@ - + - + @@ -720,12 +789,12 @@ - + - + @@ -803,7 +872,7 @@ - + @@ -813,12 +882,12 @@ - + - + @@ -974,12 +1043,12 @@ - + - + @@ -990,17 +1059,17 @@ - + + - - + @@ -1013,12 +1082,12 @@ - + - + @@ -1028,7 +1097,7 @@ - + diff --git a/Example-iOS/Source/UIkit/ExamplesViewController.swift b/Example-iOS/Source/UIkit/ExamplesViewController.swift index fe41cd7..6987f1b 100644 --- a/Example-iOS/Source/UIkit/ExamplesViewController.swift +++ b/Example-iOS/Source/UIkit/ExamplesViewController.swift @@ -15,60 +15,65 @@ class ExamplesViewController: UIViewController { // @IBSegueAction func showRiveExplorer(_ coder: NSCoder) -> UIViewController? { // return HostingController(coder: coder) // } - - @IBSegueAction func showRiveComponents(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBSegueAction func showSimpleAnimation(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBSegueAction func showLayout(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBSegueAction func showMultipleAnimations(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBSegueAction func showLoopMode(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBSegueAction func showStateMachine(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBSegueAction func showMeshExample(_ coder: NSCoder) -> UIViewController? { - return HostingController(coder: coder) - } - - @IBAction func showSwiftUISlider(_ sender: Any) { - let controller = UIHostingController(rootView: RiveSlider().view()) - navigationController?.pushViewController(controller, animated: true) - } - - @IBSegueAction func showUIKitSlider(_ coder: NSCoder) -> SimpleSliderViewController? { - return SimpleSliderViewController(coder: coder) - } - - @IBSegueAction func showUIKitMultiAnimations(_ coder: NSCoder) -> MultipleAnimationsController? { - return MultipleAnimationsController(coder: coder) - } -} - -fileprivate class HostingController: UIHostingController { - required init?(coder: NSCoder) { - super.init(coder: coder, rootView: Content()) - rootView.dismiss = { - self.dismiss(animated: true, completion: nil) - self.navigationController?.popViewController(animated: true) - } - } -} - -public protocol DismissableView: View { - init() - var dismiss: () -> Void { get set } +// +// @IBSegueAction func showRiveComponents(_ coder: NSCoder) -> UIViewController? { +// return HostingController(coder: coder) +// } +// +// @IBSegueAction func showSimpleAnimation(_ coder: NSCoder) -> UIViewController? { +// return HostingController(coder: coder) +// } +// +// @IBSegueAction func showLayout(_ coder: NSCoder) -> UIViewController? { +// return HostingController(coder: coder) +// } +// +// @IBSegueAction func showMultipleAnimations(_ coder: NSCoder) -> UIViewController? { +// return HostingController(coder: coder) +// } +// +// @IBSegueAction func showLoopMode(_ coder: NSCoder) -> UIViewController? { +// return HostingController(coder: coder) +// } +// +// @IBSegueAction func showStateMachine(_ coder: NSCoder) -> UIViewController? { +// var foo = SwiftStateMachine.self +// return HostingController(coder: coder) +// } +// +// @IBSegueAction func showMeshExample(_ coder: NSCoder) -> UIViewController? { +// return HostingController(coder: coder) +// } +// +// @IBAction func showSwiftUISlider(_ sender: Any) { +// let controller = UIHostingController(rootView: RiveSlider().view()) +// navigationController?.pushViewController(controller, animated: true) +// } +// +// @IBSegueAction func showUIKitSlider(_ coder: NSCoder) -> SimpleSliderViewController? { +// return SimpleSliderViewController(coder: coder) +// } +// +// @IBSegueAction func showUIKitMultiAnimations(_ coder: NSCoder) -> MultipleAnimationsController? { +// return MultipleAnimationsController(coder: coder) +// } } +// +//class HostingController: UIHostingController { +// override init(rootView: Content) { +// super.init(rootView: rootView) +// +// self.rootView.dismiss = { +// self.dismiss(animated: true, completion: nil) +// self.navigationController?.popViewController(animated: true) +// } +// } +// +// required init?(coder: NSCoder) { +// super.init(coder: coder, rootView: Content()) +// rootView.dismiss = { +// self.dismiss(animated: true, completion: nil) +// self.navigationController?.popViewController(animated: true) +// } +// } +//}