diff --git a/Package.resolved b/Package.resolved index 78b63197..8284a0a3 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "ab2910e7b63e3834971fd826aadfaf4e7144aad125215a16a2d786cfc73c6b2e", + "originHash" : "8fe7da0564c414438b9a41eec14d2f5d23d1ef59fdb54df060dcfa272e9cbfb2", "pins" : [ { "identity" : "bswfoundation", @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/kean/Nuke.git", "state" : { - "revision" : "158366dcdfbda52da33d419ef16ad2d00a609e9e", - "version" : "13.1.0" + "revision" : "30f7a7e72e0607d304fbf69c799474bd5fb6d1ce", + "version" : "13.2.0" } }, { diff --git a/Package.swift b/Package.swift index 86b6a6c0..68bb1ddf 100644 --- a/Package.swift +++ b/Package.swift @@ -20,12 +20,12 @@ let applePlatforms = TargetDependencyCondition.when( var packageDependencies: [Package.Dependency] = [ .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.19.4"), .package(url: "https://github.com/theleftbit/BSWFoundation.git", from: "8.0.0"), - .package(url: "https://github.com/kean/Nuke.git", from: "13.1.0"), + .package(url: "https://github.com/kean/Nuke.git", from: "13.2.0"), ] if skipIsEnabled { packageDependencies.append(contentsOf: [ - .package(url: "https://source.skip.tools/skip.git", from: "1.9.5"), + .package(url: "https://source.skip.tools/skip.git", from: "1.9.6"), .package(url: "https://source.skip.tools/skip-fuse-ui.git", from: "1.18.1"), ]) } diff --git a/Sources/BSWInterfaceKit/Shared/Extensions/UIColor+Utilities.swift b/Sources/BSWInterfaceKit/Shared/Extensions/UIColor+Utilities.swift index a141233f..d32c4ec1 100644 --- a/Sources/BSWInterfaceKit/Shared/Extensions/UIColor+Utilities.swift +++ b/Sources/BSWInterfaceKit/Shared/Extensions/UIColor+Utilities.swift @@ -52,7 +52,7 @@ public extension Color { } } -#if canImport(UIKit.UIColor) +#if canImport(UIKit) import UIKit diff --git a/Sources/BSWInterfaceKit/SwiftUI/Views/GalleryView.swift b/Sources/BSWInterfaceKit/SwiftUI/Views/GalleryView.swift index 7e36a629..60b11184 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/Views/GalleryView.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/Views/GalleryView.swift @@ -71,30 +71,13 @@ public struct GalleryView: View { cell(url, index: index) } } - .overlay(alignment: .bottom) { - PageIndicator( - itemIDs: pageIDs, - selectedID: String(currentPhotoSelectedIndex), - ) - .padding(.bottom, 16) - } - #if canImport(UIKit) + .frame(maxWidth: .infinity, maxHeight: .infinity) .toolbar { toolbarContent } - .tabViewStyle(.page(indexDisplayMode: .never)) - #endif - #if os(Android) - .navigationBarHidden(true) - .overlay(alignment: .topTrailing) { - fallbackButton - .padding([.top, .trailing], 16) - } - .tabViewStyle(.page(indexDisplayMode: .never)) - /// SkipUI renders page-style TabView as a Compose HorizontalPager, - /// which cannot be measured intrinsically. A fixed height prevents Compose - /// from crashing while measuring the full-screen gallery. - #endif + .platformPageIndicator( + itemIDs: pageIDs, + selectedID: String(currentPhotoSelectedIndex) + ) } - .frame(maxWidth: .infinity, maxHeight: .infinity) } @ViewBuilder @@ -118,18 +101,27 @@ public struct GalleryView: View { #endif } - #if canImport(UIKit) @ToolbarContentBuilder private var toolbarContent: some ToolbarContent { - ToolbarItem(placement: .topBarTrailing) { + ToolbarItem(placement: { + #if os(macOS) + .primaryAction + #else + .topBarTrailing + #endif + }()) { + #if canImport(UIKit) if #available(iOS 26.0, *) { Button(role: .close, action: dismiss.callAsFunction) } else { fallbackButton } + #elseif os(Android) + fallbackButton + #endif } } - #endif + @ViewBuilder private var fallbackButton: some View { diff --git a/Sources/BSWInterfaceKit/SwiftUI/Views/PageIndicator.swift b/Sources/BSWInterfaceKit/SwiftUI/Views/PageIndicator.swift index c6fb5793..160f6751 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/Views/PageIndicator.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/Views/PageIndicator.swift @@ -8,15 +8,37 @@ import SkipFuseUI import SwiftUI #endif -/// The native PageTabViewStyle indicator is not rendered consistently by Skip on Android. +/// Uses native page indicators on iOS and a custom indicator on Android, +/// where white native dots are not visible on white backgrounds. -public struct PageIndicator: View { +public extension View { + + @ViewBuilder + func platformPageIndicator(itemIDs: [String], selectedID: String) -> some View { + #if canImport(UIKit) + tabViewStyle(.page(indexDisplayMode: .always)) + #elseif os(Android) + tabViewStyle(.page(indexDisplayMode: .never)) + .overlay(alignment: .bottom) { + PageIndicator( + itemIDs: itemIDs, + selectedID: selectedID + ) + .padding(.bottom, 16) + } + #else + self + #endif + } +} + +struct PageIndicator: View { private let itemIDs: [String] private let selectedID: String private let color: Color - public init( + init( itemIDs: [String], selectedID: String, color: Color = .primary @@ -26,7 +48,7 @@ public struct PageIndicator: View { self.color = color } - public var body: some View { + var body: some View { HStack(spacing: 8) { ForEach(itemIDs.indices, id: \.self) { index in Circle()