Skip to content

Commit 38f8f69

Browse files
authored
1 parent ace502a commit 38f8f69

File tree

11 files changed

+85
-24
lines changed

11 files changed

+85
-24
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
- macos-12
2626
platform:
2727
- iOS
28+
- mac-catalyst
29+
- tvOS
2830
swift:
2931
- 5.5
3032
- 5.6

.spi.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ builder:
44
- platform: ios
55
scheme: NavigationTransitions
66
documentation_targets: [NavigationTransitions, NavigationTransition, AtomicTransition, Animator, Animation]
7+
- platform: macos-xcodebuild
8+
scheme: NavigationTransitions
9+
- platform: tvos
10+
scheme: NavigationTransitions

Demo/Demo.xcodeproj/project.pbxproj

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
D5535834290E9718009E5D72 /* Swing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553582C290E9718009E5D72 /* Swing.swift */; };
1313
D5535835290E9718009E5D72 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553582D290E9718009E5D72 /* RootView.swift */; };
1414
D5535836290E9718009E5D72 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553582E290E9718009E5D72 /* SceneDelegate.swift */; };
15-
D5535837290E9718009E5D72 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D553582F290E9718009E5D72 /* LaunchScreen.storyboard */; };
15+
D5535837290E9718009E5D72 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D553582F290E9718009E5D72 /* LaunchScreen.storyboard */; platformFilter = ios; };
1616
D5535839290E9718009E5D72 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5535831290E9718009E5D72 /* AppDelegate.swift */; };
1717
D553583F290E97C5009E5D72 /* NavigationTransitions in Frameworks */ = {isa = PBXBuildFile; productRef = D553583E290E97C5009E5D72 /* NavigationTransitions */; };
1818
D5535843290F4BEA009E5D72 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5535842290F4BEA009E5D72 /* AppView.swift */; };
@@ -36,6 +36,7 @@
3636
D5535842290F4BEA009E5D72 /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = "<group>"; };
3737
D5535844290F52F7009E5D72 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
3838
D5535846290F5E6F009E5D72 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
39+
D571826B291C9426003672F5 /* Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Demo.entitlements; sourceTree = "<group>"; };
3940
D5755A78291ADC00007F2201 /* Zoom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zoom.swift; sourceTree = "<group>"; };
4041
D5AAF4042911C59E009743D3 /* PageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageView.swift; sourceTree = "<group>"; };
4142
D5AAF4062911C621009743D3 /* Pages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pages.swift; sourceTree = "<group>"; };
@@ -73,6 +74,7 @@
7374
D553581D290E9691009E5D72 /* Demo */ = {
7475
isa = PBXGroup;
7576
children = (
77+
D571826B291C9426003672F5 /* Demo.entitlements */,
7678
D553583C290E978C009E5D72 /* Info.plist */,
7779
D553582F290E9718009E5D72 /* LaunchScreen.storyboard */,
7880
D5535831290E9718009E5D72 /* AppDelegate.swift */,
@@ -317,6 +319,7 @@
317319
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
318320
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
319321
CLANG_ENABLE_MODULES = YES;
322+
CODE_SIGN_ENTITLEMENTS = Demo/Demo.entitlements;
320323
CODE_SIGN_STYLE = Automatic;
321324
CURRENT_PROJECT_VERSION = 1;
322325
DEVELOPMENT_ASSET_PATHS = "\"Demo/Preview Content\"";
@@ -337,10 +340,14 @@
337340
MARKETING_VERSION = 1.0;
338341
PRODUCT_BUNDLE_IDENTIFIER = mn.dro.Demo;
339342
PRODUCT_NAME = "$(TARGET_NAME)";
343+
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator";
344+
SUPPORTS_MACCATALYST = YES;
345+
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
340346
SWIFT_EMIT_LOC_STRINGS = YES;
341347
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
342348
SWIFT_VERSION = 5.0;
343-
TARGETED_DEVICE_FAMILY = "1,2";
349+
TARGETED_DEVICE_FAMILY = "1,2,3";
350+
TVOS_DEPLOYMENT_TARGET = 13.0;
344351
};
345352
name = Debug;
346353
};
@@ -350,6 +357,7 @@
350357
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
351358
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
352359
CLANG_ENABLE_MODULES = YES;
360+
CODE_SIGN_ENTITLEMENTS = Demo/Demo.entitlements;
353361
CODE_SIGN_STYLE = Automatic;
354362
CURRENT_PROJECT_VERSION = 1;
355363
DEVELOPMENT_ASSET_PATHS = "\"Demo/Preview Content\"";
@@ -370,9 +378,13 @@
370378
MARKETING_VERSION = 1.0;
371379
PRODUCT_BUNDLE_IDENTIFIER = mn.dro.Demo;
372380
PRODUCT_NAME = "$(TARGET_NAME)";
381+
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator";
382+
SUPPORTS_MACCATALYST = YES;
383+
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
373384
SWIFT_EMIT_LOC_STRINGS = YES;
374385
SWIFT_VERSION = 5.0;
375-
TARGETED_DEVICE_FAMILY = "1,2";
386+
TARGETED_DEVICE_FAMILY = "1,2,3";
387+
TVOS_DEPLOYMENT_TARGET = 13.0;
376388
};
377389
name = Release;
378390
};

Demo/Demo/AppDelegate.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import SwiftUI
22

33
@main
44
final class AppDelegate: UIResponder, UIApplicationDelegate {
5+
#if !os(tvOS)
56
func applicationDidFinishLaunching(_ application: UIApplication) {
67
customizeNavigationBarAppearance()
78
customizeTabBarAppearance()
@@ -18,7 +19,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
1819
proxy.scrollEdgeAppearance = customAppearance
1920
proxy.compactAppearance = customAppearance
2021
proxy.standardAppearance = customAppearance
21-
if #available(iOS 15.0, *) {
22+
if #available(iOS 15.0, tvOS 15, *) {
2223
proxy.compactScrollEdgeAppearance = customAppearance
2324
}
2425
}
@@ -31,10 +32,11 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
3132

3233
let proxy = UITabBar.appearance()
3334
proxy.standardAppearance = customAppearance
34-
if #available(iOS 15, *) {
35+
if #available(iOS 15, tvOS 15, *) {
3536
proxy.scrollEdgeAppearance = customAppearance
3637
}
3738
}
39+
#endif
3840

3941
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
4042
UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)

Demo/Demo/Demo.entitlements

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.app-sandbox</key>
6+
<true/>
7+
<key>com.apple.security.network.client</key>
8+
<true/>
9+
</dict>
10+
</plist>

Demo/Demo/PageView.swift

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct PageView<Content: View, Link: View, Destination: View>: View {
1414
ZStack {
1515
Rectangle()
1616
.do {
17-
if #available(iOS 16, *) {
17+
if #available(iOS 16, tvOS 16, *) {
1818
$0.fill(color.gradient)
1919
} else {
2020
$0.fill(color)
@@ -33,23 +33,34 @@ struct PageView<Content: View, Link: View, Destination: View>: View {
3333
.shadow(color: .white.opacity(0.25), radius: 1, x: 0, y: 1)
3434
.frame(maxWidth: .infinity, maxHeight: .infinity)
3535
.foregroundColor(Color(white: 0.14))
36-
if let link = link, let destination = destination {
37-
if #available(iOS 16, *) {
38-
NavigationLink(value: number + 1) { link }
39-
} else {
40-
NavigationLink(destination: destination) { link }
36+
.frame(maxWidth: 1200)
37+
38+
Group {
39+
if let link = link, let destination = destination {
40+
if #available(iOS 16, tvOS 16, *) {
41+
NavigationLink(value: number + 1) { link }
42+
} else {
43+
NavigationLink(destination: destination) { link }
44+
}
4145
}
4246
}
47+
#if os(tvOS)
48+
.frame(maxWidth: 600)
49+
#else
50+
.frame(maxWidth: 300)
51+
#endif
4352
}
4453
.multilineTextAlignment(.center)
4554
.padding(.horizontal)
4655
.padding(.bottom, 30)
4756
}
57+
#if !os(tvOS)
4858
.navigationBarTitle(Text(title), displayMode: .inline)
59+
#endif
4960
.navigationBarItems(
5061
trailing: Button(action: { appState.isPresentingSettings = true }) {
5162
Group {
52-
if #available(iOS 14, *) {
63+
if #available(iOS 14, tvOS 16, *) {
5364
Image(systemName: "gearshape")
5465
} else {
5566
Image(systemName: "gear")

Demo/Demo/Pages.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct PageOne: View {
1414
PageTwo()
1515
}
1616
.do {
17-
if #available(iOS 16, *) {
17+
if #available(iOS 16, tvOS 16, *) {
1818
$0.navigationDestination(for: Int.self) { number in
1919
switch number {
2020
case 1: PageOne()
@@ -125,10 +125,14 @@ struct PageLink: View {
125125

126126
var body: some View {
127127
ZStack {
128+
#if !os(tvOS)
128129
RoundedRectangle(cornerRadius: 6, style: .continuous)
129130
.fill(Color.blue.opacity(0.8))
131+
#endif
130132
Text(title)
133+
#if !os(tvOS)
131134
.foregroundColor(.white)
135+
#endif
132136
.font(.system(size: 18, weight: .medium, design: .rounded))
133137
}
134138
.frame(maxHeight: 50)
@@ -150,20 +154,22 @@ struct Code<Content: StringProtocol>: View {
150154
let shape = RoundedRectangle(cornerRadius: 4, style: .circular)
151155

152156
Text(content)
153-
.frame(maxWidth: .infinity, alignment: .leading)
157+
.frame(maxWidth: 500, alignment: .leading)
154158
.padding(10)
155159
.lineLimit(lineLimit)
156160
.multilineTextAlignment(.leading)
157161
.minimumScaleFactor(0.5)
158162
.font(.system(size: 14, design: .monospaced))
159163
.background(shape.stroke(Color(white: 0.1).opacity(0.35), lineWidth: 1))
160164
.background(Color(white: 0.94).opacity(0.6).clipShape(shape))
165+
#if !os(tvOS)
161166
.do {
162167
if #available(iOS 15, *) {
163168
$0.textSelection(.enabled)
164169
} else {
165170
$0
166171
}
167172
}
173+
#endif
168174
}
169175
}

Demo/Demo/RootView.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct RootView: View {
66

77
var body: some View {
88
Group {
9-
if #available(iOS 16, *) {
9+
if #available(iOS 16, tvOS 16, *) {
1010
NavigationStack {
1111
PageOne()
1212
}
@@ -21,6 +21,8 @@ struct RootView: View {
2121
appState.transition().animation(appState.animation()),
2222
interactivity: appState.interactivity()
2323
)
24-
.sheet(isPresented: $appState.isPresentingSettings, content: SettingsView.init)
24+
.sheet(isPresented: $appState.isPresentingSettings) {
25+
SettingsView().environmentObject(appState)
26+
}
2527
}
2628
}

Demo/Demo/SettingsView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ struct SettingsView: View {
2020
picker("Interactivity", $appState.interactivity)
2121
}
2222
}
23+
#if !os(tvOS)
2324
.navigationBarTitle("Settings", displayMode: .inline)
25+
#endif
2426
.navigationBarItems(
2527
leading: Button("Shuffle", action: shuffle),
2628
trailing: Button(action: dismiss) { Text("Done").bold() }

Package.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ let package = Package(
77
name: "swiftui-navigation-transitions",
88
platforms: [
99
.iOS(.v13),
10+
.macCatalyst(.v13),
11+
.tvOS(.v13),
1012
]
1113
)
1214

Sources/NavigationTransitions/NavigationTransition+UIKit.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ extension UISplitViewController {
5353

5454
extension UISplitViewController {
5555
var compactViewController: UIViewController? {
56-
if #available(iOS 14, *) {
56+
if #available(iOS 14, tvOS 14, *) {
5757
return viewController(for: .compact)
5858
} else {
5959
if isCollapsed {
@@ -65,7 +65,7 @@ extension UISplitViewController {
6565
}
6666

6767
var primaryViewController: UIViewController? {
68-
if #available(iOS 14, *) {
68+
if #available(iOS 14, tvOS 14, *) {
6969
return viewController(for: .primary)
7070
} else {
7171
if !isCollapsed {
@@ -77,7 +77,7 @@ extension UISplitViewController {
7777
}
7878

7979
var supplementaryViewController: UIViewController? {
80-
if #available(iOS 14, *) {
80+
if #available(iOS 14, tvOS 14, *) {
8181
return viewController(for: .supplementary)
8282
} else {
8383
if !isCollapsed {
@@ -93,7 +93,7 @@ extension UISplitViewController {
9393
}
9494

9595
var secondaryViewController: UIViewController? {
96-
if #available(iOS 14, *) {
96+
if #available(iOS 14, tvOS 14, *) {
9797
return viewController(for: .secondary)
9898
} else {
9999
if !isCollapsed {
@@ -142,6 +142,13 @@ extension UINavigationController {
142142
defaultDelegate = delegate
143143
}
144144

145+
if transition.type == Default.self {
146+
delegate = defaultDelegate
147+
} else {
148+
customDelegate = NavigationTransitionDelegate(transition: transition, baseDelegate: defaultDelegate)
149+
}
150+
151+
#if !os(tvOS)
145152
if defaultPanRecognizer == nil {
146153
defaultPanRecognizer = UIPanGestureRecognizer()
147154
defaultPanRecognizer.targets = defaultEdgePanRecognizer?.targets // https://stackoverflow.com/a/60526328/1922543
@@ -165,8 +172,6 @@ extension UINavigationController {
165172
}
166173

167174
if transition.type == Default.self {
168-
delegate = defaultDelegate
169-
170175
switch interactivity {
171176
case .disabled:
172177
exclusivelyEnableGestureRecognizer(.none)
@@ -176,8 +181,6 @@ extension UINavigationController {
176181
exclusivelyEnableGestureRecognizer(defaultPanRecognizer)
177182
}
178183
} else {
179-
customDelegate = NavigationTransitionDelegate(transition: transition, baseDelegate: defaultDelegate)
180-
181184
switch interactivity {
182185
case .disabled:
183186
exclusivelyEnableGestureRecognizer(.none)
@@ -187,8 +190,10 @@ extension UINavigationController {
187190
exclusivelyEnableGestureRecognizer(panRecognizer)
188191
}
189192
}
193+
#endif
190194
}
191195

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

208+
@available(tvOS, unavailable)
203209
extension UINavigationController {
204210
var defaultEdgePanRecognizer: UIScreenEdgePanGestureRecognizer! {
205211
interactivePopGestureRecognizer as? UIScreenEdgePanGestureRecognizer
@@ -225,6 +231,7 @@ extension UINavigationController {
225231
}
226232
}
227233

234+
@available(tvOS, unavailable)
228235
extension UIGestureRecognizer {
229236
private static var strongDelegateKey = "strongDelegateKey"
230237

@@ -252,6 +259,7 @@ extension UIGestureRecognizer {
252259
}
253260
}
254261

262+
@available(tvOS, unavailable)
255263
final class NavigationGestureRecognizerDelegate: NSObject, UIGestureRecognizerDelegate {
256264
private unowned let navigationController: UINavigationController
257265

0 commit comments

Comments
 (0)