Improve Catalyst appearance
- Revert to more "stable" iPad idiom - Set accent color the proper way - Use .tint when available - Unify navigation style by idiom - Retain navigation bars in sidebar/detail - Lighten sidebar appearance - Fix Menu style (dropdown -> button) - Use native Picker (dropdown) - Use switch toggles rather than checkboxes - Replace .actionSheet with .alert - Increase minimum row height CAVEAT: on Mac with iPad idiom, having a Section in .sidebar produces artifacts. Header keeps changing height for no reason. Retain Section on iPad multitasking only to not break navigation.
This commit is contained in:
parent
eaaa1fe260
commit
743facca6b
|
@ -1229,6 +1229,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Passepartout/App/App.entitlements;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
|
@ -1245,6 +1246,7 @@
|
|||
PROVISIONING_PROFILE_SPECIFIER = "match Development com.algoritmico.ios.Passepartout";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match Development com.algoritmico.ios.Passepartout catalyst";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -1252,6 +1254,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Passepartout/App/App.entitlements;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
|
@ -1267,6 +1270,7 @@
|
|||
PRODUCT_NAME = Passepartout;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match Development com.algoritmico.ios.Passepartout";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match Development com.algoritmico.ios.Passepartout catalyst";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ internal typealias AssetImageTypeAlias = ImageAsset.Image
|
|||
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||
internal enum Asset {
|
||||
internal enum Assets {
|
||||
internal static let accentColor = ColorAsset(name: "accentColor")
|
||||
internal static let accentColor = ColorAsset(name: "AccentColor")
|
||||
internal static let lightTextColor = ColorAsset(name: "lightTextColor")
|
||||
internal static let logo = ImageAsset(name: "logo")
|
||||
internal static let primaryColor = ColorAsset(name: "primaryColor")
|
||||
|
|
|
@ -57,16 +57,30 @@ extension View {
|
|||
|
||||
extension View {
|
||||
func themeGlobal() -> some View {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
self
|
||||
#else
|
||||
let color = themeAccentColor
|
||||
return accentColor(color)
|
||||
.toggleStyle(SwitchToggleStyle(tint: color))
|
||||
.themeNavigationViewStyle()
|
||||
#endif
|
||||
themeNavigationViewStyle()
|
||||
.themeTint()
|
||||
.themeToggleStyle()
|
||||
.menuStyle(.borderlessButton)
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private func themeTint() -> some View {
|
||||
if #available(iOS 15, *) {
|
||||
tint(.accentColor)
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func themeToggleStyle() -> some View {
|
||||
if #available(iOS 15, *) {
|
||||
toggleStyle(.switch)
|
||||
} else {
|
||||
toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func themeNavigationViewStyle() -> some View {
|
||||
switch themeIdiom {
|
||||
|
@ -80,29 +94,22 @@ extension View {
|
|||
|
||||
func themePrimaryView() -> some View {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
navigationBarHidden(true)
|
||||
navigationBarTitleDisplayMode(.inline)
|
||||
#else
|
||||
navigationBarTitleDisplayMode(.large)
|
||||
.navigationTitle(Unlocalized.appName)
|
||||
#endif
|
||||
}
|
||||
|
||||
func themeSecondaryView() -> some View {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
navigationBarHidden(true)
|
||||
#else
|
||||
navigationBarTitleDisplayMode(.inline)
|
||||
.listStyle(.insetGrouped)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Colors
|
||||
|
||||
extension View {
|
||||
fileprivate var themeAccentColor: Color {
|
||||
Color(Asset.Assets.accentColor.color)
|
||||
}
|
||||
|
||||
fileprivate var themePrimaryBackgroundColor: Color {
|
||||
Color(Asset.Assets.primaryColor.color)
|
||||
}
|
||||
|
@ -307,15 +314,15 @@ extension String {
|
|||
// MARK: Styles
|
||||
|
||||
extension View {
|
||||
func themeAccentForegroundStyle() -> some View {
|
||||
foregroundColor(.accentColor)
|
||||
}
|
||||
|
||||
var themePrimaryBackground: some View {
|
||||
themePrimaryBackgroundColor
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
|
||||
func themeAccentForegroundStyle() -> some View {
|
||||
foregroundColor(themeAccentColor)
|
||||
}
|
||||
|
||||
func themeSecondaryTextStyle() -> some View {
|
||||
foregroundColor(themeSecondaryColor)
|
||||
}
|
||||
|
|
|
@ -112,7 +112,6 @@ struct OrganizerView: View {
|
|||
allowsMultipleSelection: false,
|
||||
onCompletion: onHostFileImporterResult
|
||||
).onOpenURL(perform: onOpenURL)
|
||||
.navigationTitle(Unlocalized.appName)
|
||||
.themePrimaryView()
|
||||
}
|
||||
|
||||
|
|
|
@ -83,26 +83,22 @@ extension ProfileView {
|
|||
deleteProfileButton
|
||||
} label: {
|
||||
themeSettingsMenuImage.asSystemImage
|
||||
}.actionSheet(item: $actionSheetType) {
|
||||
}.alert(item: $actionSheetType) {
|
||||
switch $0 {
|
||||
case .uninstallVPN:
|
||||
return ActionSheet(
|
||||
title: Text(L10n.Profile.Alerts.UninstallVpn.message),
|
||||
message: nil,
|
||||
buttons: [
|
||||
.destructive(Text(uninstallVPNTitle), action: uninstallVPN),
|
||||
.cancel(Text(cancelTitle))
|
||||
]
|
||||
return Alert(
|
||||
title: Text(uninstallVPNTitle),
|
||||
message: Text(L10n.Profile.Alerts.UninstallVpn.message),
|
||||
primaryButton: .destructive(Text(uninstallVPNTitle), action: uninstallVPN),
|
||||
secondaryButton: .cancel(Text(cancelTitle))
|
||||
)
|
||||
|
||||
case .deleteProfile:
|
||||
return ActionSheet(
|
||||
title: Text(L10n.Organizer.Alerts.RemoveProfile.message(header.name)),
|
||||
message: nil,
|
||||
buttons: [
|
||||
.destructive(Text(deleteProfileTitle), action: removeProfile),
|
||||
.cancel(Text(cancelTitle))
|
||||
]
|
||||
return Alert(
|
||||
title: Text(deleteProfileTitle),
|
||||
message: Text(L10n.Organizer.Alerts.RemoveProfile.message(header.name)),
|
||||
primaryButton: .destructive(Text(deleteProfileTitle), action: removeProfile),
|
||||
secondaryButton: .cancel(Text(cancelTitle))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue