Skip to content

Commit

Permalink
macCatalyst, tvOS support (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
davdroman authored Nov 10, 2022
1 parent ace502a commit 38f8f69
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 24 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
- macos-12
platform:
- iOS
- mac-catalyst
- tvOS
swift:
- 5.5
- 5.6
Expand Down
4 changes: 4 additions & 0 deletions .spi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ builder:
- platform: ios
scheme: NavigationTransitions
documentation_targets: [NavigationTransitions, NavigationTransition, AtomicTransition, Animator, Animation]
- platform: macos-xcodebuild
scheme: NavigationTransitions
- platform: tvos
scheme: NavigationTransitions
18 changes: 15 additions & 3 deletions Demo/Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
D5535834290E9718009E5D72 /* Swing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553582C290E9718009E5D72 /* Swing.swift */; };
D5535835290E9718009E5D72 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553582D290E9718009E5D72 /* RootView.swift */; };
D5535836290E9718009E5D72 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553582E290E9718009E5D72 /* SceneDelegate.swift */; };
D5535837290E9718009E5D72 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D553582F290E9718009E5D72 /* LaunchScreen.storyboard */; };
D5535837290E9718009E5D72 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D553582F290E9718009E5D72 /* LaunchScreen.storyboard */; platformFilter = ios; };
D5535839290E9718009E5D72 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5535831290E9718009E5D72 /* AppDelegate.swift */; };
D553583F290E97C5009E5D72 /* NavigationTransitions in Frameworks */ = {isa = PBXBuildFile; productRef = D553583E290E97C5009E5D72 /* NavigationTransitions */; };
D5535843290F4BEA009E5D72 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5535842290F4BEA009E5D72 /* AppView.swift */; };
Expand All @@ -36,6 +36,7 @@
D5535842290F4BEA009E5D72 /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = "<group>"; };
D5535844290F52F7009E5D72 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
D5535846290F5E6F009E5D72 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
D571826B291C9426003672F5 /* Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Demo.entitlements; sourceTree = "<group>"; };
D5755A78291ADC00007F2201 /* Zoom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zoom.swift; sourceTree = "<group>"; };
D5AAF4042911C59E009743D3 /* PageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageView.swift; sourceTree = "<group>"; };
D5AAF4062911C621009743D3 /* Pages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pages.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -73,6 +74,7 @@
D553581D290E9691009E5D72 /* Demo */ = {
isa = PBXGroup;
children = (
D571826B291C9426003672F5 /* Demo.entitlements */,
D553583C290E978C009E5D72 /* Info.plist */,
D553582F290E9718009E5D72 /* LaunchScreen.storyboard */,
D5535831290E9718009E5D72 /* AppDelegate.swift */,
Expand Down Expand Up @@ -317,6 +319,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Demo/Demo.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Demo/Preview Content\"";
Expand All @@ -337,10 +340,14 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = mn.dro.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = YES;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = "1,2,3";
TVOS_DEPLOYMENT_TARGET = 13.0;
};
name = Debug;
};
Expand All @@ -350,6 +357,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Demo/Demo.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Demo/Preview Content\"";
Expand All @@ -370,9 +378,13 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = mn.dro.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = YES;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = "1,2,3";
TVOS_DEPLOYMENT_TARGET = 13.0;
};
name = Release;
};
Expand Down
6 changes: 4 additions & 2 deletions Demo/Demo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import SwiftUI

@main
final class AppDelegate: UIResponder, UIApplicationDelegate {
#if !os(tvOS)
func applicationDidFinishLaunching(_ application: UIApplication) {
customizeNavigationBarAppearance()
customizeTabBarAppearance()
Expand All @@ -18,7 +19,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
proxy.scrollEdgeAppearance = customAppearance
proxy.compactAppearance = customAppearance
proxy.standardAppearance = customAppearance
if #available(iOS 15.0, *) {
if #available(iOS 15.0, tvOS 15, *) {
proxy.compactScrollEdgeAppearance = customAppearance
}
}
Expand All @@ -31,10 +32,11 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {

let proxy = UITabBar.appearance()
proxy.standardAppearance = customAppearance
if #available(iOS 15, *) {
if #available(iOS 15, tvOS 15, *) {
proxy.scrollEdgeAppearance = customAppearance
}
}
#endif

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
Expand Down
10 changes: 10 additions & 0 deletions Demo/Demo/Demo.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
25 changes: 18 additions & 7 deletions Demo/Demo/PageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct PageView<Content: View, Link: View, Destination: View>: View {
ZStack {
Rectangle()
.do {
if #available(iOS 16, *) {
if #available(iOS 16, tvOS 16, *) {
$0.fill(color.gradient)
} else {
$0.fill(color)
Expand All @@ -33,23 +33,34 @@ struct PageView<Content: View, Link: View, Destination: View>: View {
.shadow(color: .white.opacity(0.25), radius: 1, x: 0, y: 1)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundColor(Color(white: 0.14))
if let link = link, let destination = destination {
if #available(iOS 16, *) {
NavigationLink(value: number + 1) { link }
} else {
NavigationLink(destination: destination) { link }
.frame(maxWidth: 1200)

Group {
if let link = link, let destination = destination {
if #available(iOS 16, tvOS 16, *) {
NavigationLink(value: number + 1) { link }
} else {
NavigationLink(destination: destination) { link }
}
}
}
#if os(tvOS)
.frame(maxWidth: 600)
#else
.frame(maxWidth: 300)
#endif
}
.multilineTextAlignment(.center)
.padding(.horizontal)
.padding(.bottom, 30)
}
#if !os(tvOS)
.navigationBarTitle(Text(title), displayMode: .inline)
#endif
.navigationBarItems(
trailing: Button(action: { appState.isPresentingSettings = true }) {
Group {
if #available(iOS 14, *) {
if #available(iOS 14, tvOS 16, *) {
Image(systemName: "gearshape")
} else {
Image(systemName: "gear")
Expand Down
10 changes: 8 additions & 2 deletions Demo/Demo/Pages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct PageOne: View {
PageTwo()
}
.do {
if #available(iOS 16, *) {
if #available(iOS 16, tvOS 16, *) {
$0.navigationDestination(for: Int.self) { number in
switch number {
case 1: PageOne()
Expand Down Expand Up @@ -125,10 +125,14 @@ struct PageLink: View {

var body: some View {
ZStack {
#if !os(tvOS)
RoundedRectangle(cornerRadius: 6, style: .continuous)
.fill(Color.blue.opacity(0.8))
#endif
Text(title)
#if !os(tvOS)
.foregroundColor(.white)
#endif
.font(.system(size: 18, weight: .medium, design: .rounded))
}
.frame(maxHeight: 50)
Expand All @@ -150,20 +154,22 @@ struct Code<Content: StringProtocol>: View {
let shape = RoundedRectangle(cornerRadius: 4, style: .circular)

Text(content)
.frame(maxWidth: .infinity, alignment: .leading)
.frame(maxWidth: 500, alignment: .leading)
.padding(10)
.lineLimit(lineLimit)
.multilineTextAlignment(.leading)
.minimumScaleFactor(0.5)
.font(.system(size: 14, design: .monospaced))
.background(shape.stroke(Color(white: 0.1).opacity(0.35), lineWidth: 1))
.background(Color(white: 0.94).opacity(0.6).clipShape(shape))
#if !os(tvOS)
.do {
if #available(iOS 15, *) {
$0.textSelection(.enabled)
} else {
$0
}
}
#endif
}
}
6 changes: 4 additions & 2 deletions Demo/Demo/RootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct RootView: View {

var body: some View {
Group {
if #available(iOS 16, *) {
if #available(iOS 16, tvOS 16, *) {
NavigationStack {
PageOne()
}
Expand All @@ -21,6 +21,8 @@ struct RootView: View {
appState.transition().animation(appState.animation()),
interactivity: appState.interactivity()
)
.sheet(isPresented: $appState.isPresentingSettings, content: SettingsView.init)
.sheet(isPresented: $appState.isPresentingSettings) {
SettingsView().environmentObject(appState)
}
}
}
2 changes: 2 additions & 0 deletions Demo/Demo/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ struct SettingsView: View {
picker("Interactivity", $appState.interactivity)
}
}
#if !os(tvOS)
.navigationBarTitle("Settings", displayMode: .inline)
#endif
.navigationBarItems(
leading: Button("Shuffle", action: shuffle),
trailing: Button(action: dismiss) { Text("Done").bold() }
Expand Down
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ let package = Package(
name: "swiftui-navigation-transitions",
platforms: [
.iOS(.v13),
.macCatalyst(.v13),
.tvOS(.v13),
]
)

Expand Down
24 changes: 16 additions & 8 deletions Sources/NavigationTransitions/NavigationTransition+UIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extension UISplitViewController {

extension UISplitViewController {
var compactViewController: UIViewController? {
if #available(iOS 14, *) {
if #available(iOS 14, tvOS 14, *) {
return viewController(for: .compact)
} else {
if isCollapsed {
Expand All @@ -65,7 +65,7 @@ extension UISplitViewController {
}

var primaryViewController: UIViewController? {
if #available(iOS 14, *) {
if #available(iOS 14, tvOS 14, *) {
return viewController(for: .primary)
} else {
if !isCollapsed {
Expand All @@ -77,7 +77,7 @@ extension UISplitViewController {
}

var supplementaryViewController: UIViewController? {
if #available(iOS 14, *) {
if #available(iOS 14, tvOS 14, *) {
return viewController(for: .supplementary)
} else {
if !isCollapsed {
Expand All @@ -93,7 +93,7 @@ extension UISplitViewController {
}

var secondaryViewController: UIViewController? {
if #available(iOS 14, *) {
if #available(iOS 14, tvOS 14, *) {
return viewController(for: .secondary)
} else {
if !isCollapsed {
Expand Down Expand Up @@ -142,6 +142,13 @@ extension UINavigationController {
defaultDelegate = delegate
}

if transition.type == Default.self {
delegate = defaultDelegate
} else {
customDelegate = NavigationTransitionDelegate(transition: transition, baseDelegate: defaultDelegate)
}

#if !os(tvOS)
if defaultPanRecognizer == nil {
defaultPanRecognizer = UIPanGestureRecognizer()
defaultPanRecognizer.targets = defaultEdgePanRecognizer?.targets // https://stackoverflow.com/a/60526328/1922543
Expand All @@ -165,8 +172,6 @@ extension UINavigationController {
}

if transition.type == Default.self {
delegate = defaultDelegate

switch interactivity {
case .disabled:
exclusivelyEnableGestureRecognizer(.none)
Expand All @@ -176,8 +181,6 @@ extension UINavigationController {
exclusivelyEnableGestureRecognizer(defaultPanRecognizer)
}
} else {
customDelegate = NavigationTransitionDelegate(transition: transition, baseDelegate: defaultDelegate)

switch interactivity {
case .disabled:
exclusivelyEnableGestureRecognizer(.none)
Expand All @@ -187,8 +190,10 @@ extension UINavigationController {
exclusivelyEnableGestureRecognizer(panRecognizer)
}
}
#endif
}

@available(tvOS, unavailable)
private func exclusivelyEnableGestureRecognizer(_ gestureRecognizer: UIPanGestureRecognizer?) {
for recognizer in [defaultEdgePanRecognizer!, defaultPanRecognizer!, edgePanRecognizer!, panRecognizer!] {
if let gestureRecognizer = gestureRecognizer, recognizer === gestureRecognizer {
Expand All @@ -200,6 +205,7 @@ extension UINavigationController {
}
}

@available(tvOS, unavailable)
extension UINavigationController {
var defaultEdgePanRecognizer: UIScreenEdgePanGestureRecognizer! {
interactivePopGestureRecognizer as? UIScreenEdgePanGestureRecognizer
Expand All @@ -225,6 +231,7 @@ extension UINavigationController {
}
}

@available(tvOS, unavailable)
extension UIGestureRecognizer {
private static var strongDelegateKey = "strongDelegateKey"

Expand Down Expand Up @@ -252,6 +259,7 @@ extension UIGestureRecognizer {
}
}

@available(tvOS, unavailable)
final class NavigationGestureRecognizerDelegate: NSObject, UIGestureRecognizerDelegate {
private unowned let navigationController: UINavigationController

Expand Down

0 comments on commit 38f8f69

Please sign in to comment.