fix(apple/iOS): touch-first control sizing — toolbar circles + large sheet buttons
ci / rust (push) Has been cancelled
ci / rust (push) Has been cancelled
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 <noreply@anthropic.com>
This commit is contained in:
@@ -299,10 +299,12 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEVELOPMENT_TEAM = F4H37KF6WC;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
@@ -317,6 +319,8 @@
|
|||||||
MARKETING_VERSION = 0.1;
|
MARKETING_VERSION = 0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.unom.punktfunk;
|
PRODUCT_BUNDLE_IDENTIFIER = io.unom.punktfunk;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SUPPORTED_PLATFORMS = macosx;
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
@@ -327,10 +331,12 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEVELOPMENT_TEAM = F4H37KF6WC;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
@@ -345,17 +351,20 @@
|
|||||||
MARKETING_VERSION = 0.1;
|
MARKETING_VERSION = 0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.unom.punktfunk;
|
PRODUCT_BUNDLE_IDENTIFIER = io.unom.punktfunk;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SUPPORTED_PLATFORMS = macosx;
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
BB0000000000000000000012 /* Debug */ = {
|
BB0000000000000000000012 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = F4H37KF6WC;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
@@ -377,6 +386,8 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@@ -389,6 +400,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
ASSETCATALOG_COMPILER_APPICON_NAME = punktfunk_Logo;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = F4H37KF6WC;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
INFOPLIST_KEY_CFBundleDisplayName = "Punktfunkempfänger";
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
@@ -410,6 +422,8 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@@ -419,15 +433,6 @@
|
|||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList 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" */ = {
|
AA000000000000000000000A /* Build configuration list for PBXNativeTarget "Punktfunk" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
@@ -446,6 +451,15 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
BB000000000000000000000A /* Build configuration list for PBXNativeTarget "Punktfunk-iOS" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
BB0000000000000000000012 /* Debug */,
|
||||||
|
BB0000000000000000000013 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCLocalSwiftPackageReference section */
|
/* Begin XCLocalSwiftPackageReference section */
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ struct AddHostSheet: View {
|
|||||||
.keyboardShortcut(.defaultAction)
|
.keyboardShortcut(.defaultAction)
|
||||||
.disabled(address.trimmingCharacters(in: .whitespaces).isEmpty)
|
.disabled(address.trimmingCharacters(in: .whitespaces).isEmpty)
|
||||||
}
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
.controlSize(.large)
|
||||||
|
#endif
|
||||||
.padding(16)
|
.padding(16)
|
||||||
}
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
|
|||||||
@@ -104,28 +104,29 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
.navigationTitle("punktfunk")
|
.navigationTitle("punktfunk")
|
||||||
.toolbar {
|
.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) {
|
ToolbarItem(placement: .primaryAction) {
|
||||||
Button {
|
addHostButton
|
||||||
showAddHost = true
|
.help("Add a host")
|
||||||
} label: {
|
|
||||||
Label("Add Host", systemImage: "plus")
|
|
||||||
}
|
|
||||||
.help("Add a host")
|
|
||||||
}
|
}
|
||||||
ToolbarItem {
|
ToolbarItem {
|
||||||
#if os(macOS)
|
|
||||||
SettingsLink {
|
SettingsLink {
|
||||||
Label("Settings", systemImage: "gearshape")
|
Label("Settings", systemImage: "gearshape")
|
||||||
}
|
}
|
||||||
.help("Stream mode and settings")
|
.help("Stream mode and settings")
|
||||||
#else
|
|
||||||
Button {
|
|
||||||
showSettings = true
|
|
||||||
} label: {
|
|
||||||
Label("Settings", systemImage: "gearshape")
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if os(macOS)
|
#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 {
|
private var emptyState: some View {
|
||||||
ContentUnavailableView {
|
ContentUnavailableView {
|
||||||
Label("No Hosts", systemImage: "rectangle.connected.to.line.below")
|
Label("No Hosts", systemImage: "rectangle.connected.to.line.below")
|
||||||
@@ -166,6 +185,9 @@ struct ContentView: View {
|
|||||||
} actions: {
|
} actions: {
|
||||||
Button("Add Host") { showAddHost = true }
|
Button("Add Host") { showAddHost = true }
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
#if os(iOS)
|
||||||
|
.controlSize(.large)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,6 +282,9 @@ struct ContentView: View {
|
|||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
.keyboardShortcut(.defaultAction)
|
.keyboardShortcut(.defaultAction)
|
||||||
}
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
.controlSize(.large)
|
||||||
|
#endif
|
||||||
// The verified alternative to eyeballing hex: drop this session (the host
|
// The verified alternative to eyeballing hex: drop this session (the host
|
||||||
// serves one connection at a time) and run the SPAKE2 PIN ceremony instead.
|
// serves one connection at a time) and run the SPAKE2 PIN ceremony instead.
|
||||||
Button("Pair with PIN instead…") {
|
Button("Pair with PIN instead…") {
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ struct PairSheet: View {
|
|||||||
.keyboardShortcut(.defaultAction)
|
.keyboardShortcut(.defaultAction)
|
||||||
.disabled(busy || pin.trimmingCharacters(in: .whitespaces).isEmpty)
|
.disabled(busy || pin.trimmingCharacters(in: .whitespaces).isEmpty)
|
||||||
}
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
.controlSize(.large)
|
||||||
|
#endif
|
||||||
.padding(16)
|
.padding(16)
|
||||||
}
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
|
|||||||
Reference in New Issue
Block a user