-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDetailView.swift
More file actions
90 lines (81 loc) · 3.44 KB
/
DetailView.swift
File metadata and controls
90 lines (81 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
See the LICENSE.txt file for this sample’s licensing information.
Abstract:
A view that presents the video detail view in iOS.
*/
import SwiftUI
struct DetailView: View {
let video: Video
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Environment(PlayerModel.self) private var player
@Environment(VideoLibrary.self) private var library
var body: some View {
GeometryReader() { geometry in
ZStack(alignment: .bottom) {
// The background view and gradient.
Group {
// Show a geometry-appropriate background image.
backgroundImage(for: geometry)
// The gradient overlay view.
gradientOverlay
}
.ignoresSafeArea()
// The compact width video info layout.
if horizontalSizeClass == .compact {
VStack {
Text(video.title)
.font(.title.weight(.semibold))
InfoLineView(year: video.info.releaseYear,
rating: video.info.contentRating,
duration: video.info.duration)
Button {
/// Load the media item for full-window presentation.
player.loadVideo(video, presentation: .fullWindow)
} label: {
Label("Play Video", systemImage: "play.fill")
.fontWeight(.semibold)
.foregroundStyle(.black)
}
.buttonStyle(.borderedProminent)
Text(video.description)
.padding()
}
} else {
// The regular width video info layout.
VStack {
Text(video.title)
.font(.largeTitle).bold()
// iPadOS and tvOS share this view to present the video detail information.
WideDetailView(video: video, player: player, library: library)
}
}
}
}
// Don't show a navigation title in iOS.
.navigationTitle("")
}
/// Returns a background image appropriate for the specified geometry.
///
/// - Parameter geometry: a geometry proxy to use for the calculation.
/// - Returns: A resizable image appropriate for the current geometry.
func backgroundImage(for geometry: GeometryProxy) -> Image {
let usePortrait = geometry.size.height > geometry.size.width
return Image(usePortrait ? video.portraitImageName : video.landscapeImageName).resizable()
}
var gradientOverlay: some View {
VStack {
// Add a subtle gradient at the top to make the back button stand out.
GradientView(style: .black.opacity(0.2), height: 120, startPoint: .bottom)
Spacer()
// Add a material gradient at bottom to show below the video's detail information.
GradientView(style: .thinMaterial, height: 400, startPoint: .top)
}
}
}
#Preview {
NavigationStack {
DetailView(video: .preview)
.environment(PlayerModel())
.environment(VideoLibrary())
}
}