Skip to content

Commit fccd4d4

Browse files
committed
Update the Example with tvOS, now it supports zooming and edit mode to delete image cells
1 parent 289e0bd commit fccd4d4

File tree

4 files changed

+59
-13
lines changed

4 files changed

+59
-13
lines changed

Example/SDWebImageSwiftUIDemo-tvOS/AppDelegate.swift

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,29 @@ import SDWebImagePDFCoder
1717
class AppDelegate: UIResponder, UIApplicationDelegate {
1818

1919
var window: UIWindow?
20-
20+
var settings = UserSettings()
2121

2222
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2323

2424
// Create the SwiftUI view that provides the window contents.
25-
let contentView = ContentView()
25+
let contentView = ContentView().environmentObject(settings)
2626

2727
// Use a UIHostingController as window root view controller.
2828
let window = UIWindow(frame: UIScreen.main.bounds)
29-
window.rootViewController = UIHostingController(rootView: contentView)
29+
let hostingController = UIHostingController(rootView: contentView)
30+
window.rootViewController = hostingController
3031
self.window = window
3132
window.makeKeyAndVisible()
33+
34+
// Hack here because of SwiftUI's bug, when using `NavigationLink`, the focusable no longer works, so the `onExitCommand` does not get called
35+
let menuGesture = UITapGestureRecognizer(target: self, action: #selector(handleMenuGesture(_:)))
36+
menuGesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.menu.rawValue)]
37+
hostingController.view.addGestureRecognizer(menuGesture)
38+
39+
let playPauseGesture = UITapGestureRecognizer(target: self, action: #selector(handlePlayPauseGesture(_:)))
40+
playPauseGesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.playPause.rawValue)]
41+
hostingController.view.addGestureRecognizer(playPauseGesture)
42+
3243
// Add WebP/SVG/PDF support
3344
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
3445
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
@@ -50,6 +61,23 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
5061

5162
return true
5263
}
64+
65+
@objc func handleMenuGesture(_ gesture: UITapGestureRecognizer) {
66+
switch settings.editMode {
67+
case .inactive:
68+
settings.editMode = .active
69+
case .active:
70+
settings.editMode = .inactive
71+
case .transient:
72+
break
73+
@unknown default:
74+
break
75+
}
76+
}
77+
78+
@objc func handlePlayPauseGesture(_ gesture: UITapGestureRecognizer) {
79+
settings.zoomed.toggle()
80+
}
5381

5482
func applicationWillResignActive(_ application: UIApplication) {
5583
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

Example/SDWebImageSwiftUIDemo/ContentView.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ import SwiftUI
1010
import SDWebImage
1111
import SDWebImageSwiftUI
1212

13+
class UserSettings: ObservableObject {
14+
// Some environment configuration
15+
@Published var editMode: EditMode = .inactive
16+
@Published var zoomed: Bool = false
17+
}
18+
1319
#if os(watchOS)
1420
// watchOS does not provide built-in indicator, use Espera's custom indicator
1521
extension Indicator where T == LoadingFlowerView {
@@ -53,11 +59,27 @@ struct ContentView: View {
5359
"https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/smartphone_tablet.pdf"
5460
]
5561
@State var animated: Bool = true // You can change between WebImage/AnimatedImage
62+
@EnvironmentObject var settings: UserSettings
5663

5764
var body: some View {
58-
#if os(iOS) || os(tvOS)
65+
#if os(iOS)
66+
return NavigationView {
67+
contentView()
68+
.navigationBarTitle(animated ? "AnimatedImage" : "WebImage")
69+
.navigationBarItems(leading:
70+
Button(action: { self.reloadCache() }) {
71+
Text("Reload")
72+
}, trailing:
73+
Button(action: { self.switchView() }) {
74+
Text("Switch")
75+
}
76+
)
77+
}
78+
#endif
79+
#if os(tvOS)
5980
return NavigationView {
6081
contentView()
82+
.environment(\EnvironmentValues.editMode, self.$settings.editMode)
6183
.navigationBarTitle(animated ? "AnimatedImage" : "WebImage")
6284
.navigationBarItems(leading:
6385
Button(action: { self.reloadCache() }) {

Example/SDWebImageSwiftUIDemo/DetailView.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct DetailView: View {
1616
@State var lastScaleValue: CGFloat = 1.0
1717
@State var scale: CGFloat = 1.0
1818
@Environment(\.presentationMode) var presentationMode
19+
@EnvironmentObject var settings: UserSettings
1920

2021
var body: some View {
2122
VStack {
@@ -60,14 +61,9 @@ struct DetailView: View {
6061
#if os(tvOS)
6162
return contentView()
6263
.scaleEffect(self.scale)
63-
.focusable(true)
64-
.onPlayPauseCommand {
65-
switch self.scale {
66-
case 1:
67-
self.scale = 2
68-
case 2:
69-
self.scale = 1
70-
default: break
64+
.onReceive(self.settings.$zoomed) { zoomed in
65+
withAnimation {
66+
self.scale = zoomed ? 2 : 1
7167
}
7268
}
7369
#endif

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ Demo Tips:
368368

369369
1. Use `Switch` (right-click on macOS/force press on watchOS) to switch between `WebImage` and `AnimatedImage`.
370370
2. Use `Reload` (right-click on macOS/force press on watchOS) to clear cache.
371-
3. Use `Swipe` to delete one image item.
371+
3. Use `Swipe To Delete` (menu button on tvOS) to delete one image url from list.
372372
4. Pinch gesture (Digital Crown on watchOS, play button on tvOS) to zoom-in detail page image.
373373
5. Clear cache and go to detail page to see progressive loading.
374374

0 commit comments

Comments
 (0)