From 7c24832ad095e061f171e0caae3a8caed1f40e73 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Thu, 11 Jun 2026 11:47:30 +0200 Subject: [PATCH] =?UTF-8?q?fix(apple/iOS):=20touch-first=20control=20sizin?= =?UTF-8?q?g=20=E2=80=94=20toolbar=20circles=20+=20large=20sheet=20buttons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iOS chrome inherited macOS dialog sizing and read as undersized on a phone: - Toolbar: the two trailing actions shared one compact glass pill; on iOS 26+ each now gets its own full-size circle (explicit .topBarTrailing placements split by a fixed ToolbarSpacer — the system-app look, e.g. Files), with the grouped-pill fallback on iOS 17–18. The buttons are extracted so macOS keeps SettingsLink + .help untouched. - Sheets and CTAs (AddHostSheet, PairSheet, trust card, empty-state Add Host) get .controlSize(.large) on iOS — proper touch targets instead of macOS dialog buttons. Verified in the iPhone 17 simulator: two ~44 pt glass circles matching the Files app's toolbar sizing; macOS suite and app build unchanged. Co-Authored-By: Claude Fable 5 --- .../apple/Punktfunk.xcodeproj/project.pbxproj | 34 ++++++++---- .../PunktfunkClient/AddHostSheet.swift | 3 ++ .../Sources/PunktfunkClient/ContentView.swift | 53 ++++++++++++++----- .../Sources/PunktfunkClient/PairSheet.swift | 3 ++ 4 files changed, 69 insertions(+), 24 deletions(-) diff --git a/clients/apple/Punktfunk.xcodeproj/project.pbxproj b/clients/apple/Punktfunk.xcodeproj/project.pbxproj index ef5f371..57235cf 100644 --- a/clients/apple/Punktfunk.xcodeproj/project.pbxproj +++ b/clients/apple/Punktfunk.xcodeproj/project.pbxproj @@ -299,10 +299,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo; CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = F4H37KF6WC; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; @@ -317,6 +319,8 @@ MARKETING_VERSION = 0.1; PRODUCT_BUNDLE_IDENTIFIER = io.unom.punktfunk; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = macosx; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; @@ -327,10 +331,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo; CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = F4H37KF6WC; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; @@ -345,17 +351,20 @@ MARKETING_VERSION = 0.1; PRODUCT_BUNDLE_IDENTIFIER = io.unom.punktfunk; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = macosx; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; name = Release; }; - BB0000000000000000000012 /* Debug */ = { + BB0000000000000000000012 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = F4H37KF6WC; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; @@ -377,6 +386,8 @@ SDKROOT = iphoneos; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -389,6 +400,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = F4H37KF6WC; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; @@ -410,6 +422,8 @@ SDKROOT = iphoneos; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -419,15 +433,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - BB000000000000000000000A /* Build configuration list for PBXNativeTarget "Punktfunk-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BB0000000000000000000012 /* Debug */, - BB0000000000000000000013 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; AA000000000000000000000A /* Build configuration list for PBXNativeTarget "Punktfunk" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -446,6 +451,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + BB000000000000000000000A /* Build configuration list for PBXNativeTarget "Punktfunk-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BB0000000000000000000012 /* Debug */, + BB0000000000000000000013 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ diff --git a/clients/apple/Sources/PunktfunkClient/AddHostSheet.swift b/clients/apple/Sources/PunktfunkClient/AddHostSheet.swift index 988f6fe..d6f12df 100644 --- a/clients/apple/Sources/PunktfunkClient/AddHostSheet.swift +++ b/clients/apple/Sources/PunktfunkClient/AddHostSheet.swift @@ -34,6 +34,9 @@ struct AddHostSheet: View { .keyboardShortcut(.defaultAction) .disabled(address.trimmingCharacters(in: .whitespaces).isEmpty) } + #if os(iOS) + .controlSize(.large) + #endif .padding(16) } #if os(macOS) diff --git a/clients/apple/Sources/PunktfunkClient/ContentView.swift b/clients/apple/Sources/PunktfunkClient/ContentView.swift index 1543366..e57ebe4 100644 --- a/clients/apple/Sources/PunktfunkClient/ContentView.swift +++ b/clients/apple/Sources/PunktfunkClient/ContentView.swift @@ -104,28 +104,29 @@ struct ContentView: View { } .navigationTitle("punktfunk") .toolbar { + #if os(iOS) + // Each action gets its own full-size glass circle (system-app style) + // instead of sharing one compact pill. + if #available(iOS 26.0, *) { + ToolbarItem(placement: .topBarTrailing) { settingsButton } + ToolbarSpacer(.fixed, placement: .topBarTrailing) + ToolbarItem(placement: .topBarTrailing) { addHostButton } + } else { + ToolbarItem { settingsButton } + ToolbarItem(placement: .primaryAction) { addHostButton } + } + #else ToolbarItem(placement: .primaryAction) { - Button { - showAddHost = true - } label: { - Label("Add Host", systemImage: "plus") - } - .help("Add a host") + addHostButton + .help("Add a host") } ToolbarItem { - #if os(macOS) SettingsLink { Label("Settings", systemImage: "gearshape") } .help("Stream mode and settings") - #else - Button { - showSettings = true - } label: { - Label("Settings", systemImage: "gearshape") - } - #endif } + #endif } } #if os(macOS) @@ -158,6 +159,24 @@ struct ContentView: View { } } + private var addHostButton: some View { + Button { + showAddHost = true + } label: { + Label("Add Host", systemImage: "plus") + } + } + + #if os(iOS) + private var settingsButton: some View { + Button { + showSettings = true + } label: { + Label("Settings", systemImage: "gearshape") + } + } + #endif + private var emptyState: some View { ContentUnavailableView { Label("No Hosts", systemImage: "rectangle.connected.to.line.below") @@ -166,6 +185,9 @@ struct ContentView: View { } actions: { Button("Add Host") { showAddHost = true } .buttonStyle(.borderedProminent) + #if os(iOS) + .controlSize(.large) + #endif } } @@ -260,6 +282,9 @@ struct ContentView: View { .buttonStyle(.borderedProminent) .keyboardShortcut(.defaultAction) } + #if os(iOS) + .controlSize(.large) + #endif // The verified alternative to eyeballing hex: drop this session (the host // serves one connection at a time) and run the SPAKE2 PIN ceremony instead. Button("Pair with PIN instead…") { diff --git a/clients/apple/Sources/PunktfunkClient/PairSheet.swift b/clients/apple/Sources/PunktfunkClient/PairSheet.swift index 068c9d9..5e030ac 100644 --- a/clients/apple/Sources/PunktfunkClient/PairSheet.swift +++ b/clients/apple/Sources/PunktfunkClient/PairSheet.swift @@ -79,6 +79,9 @@ struct PairSheet: View { .keyboardShortcut(.defaultAction) .disabled(busy || pin.trimmingCharacters(in: .whitespaces).isEmpty) } + #if os(iOS) + .controlSize(.large) + #endif .padding(16) } #if os(macOS)