mirror of
https://codeberg.org/secana/Forji.git
synced 2026-06-16 05:13:55 -07:00
fix: stop login button collapsing on press release
Give the login button a custom FlatPrimaryButtonStyle instead of .borderedProminent + .controlSize(.large). The system style's built-in press treatment springs/scales on release, which on iOS 26 read as the button's lower edge collapsing when the finger lifted. The flat style changes only background opacity on press — no scaleEffect, no spring — so the frame holds. Keeps the full-width fill, the large hit target, and the ZStack label that holds the frame steady while the loading spinner is shown. Generated with Claude Opus 4.8 (1M)
This commit is contained in:
parent
992c628abd
commit
a1dea935b0
1 changed files with 38 additions and 7 deletions
|
|
@ -144,19 +144,18 @@ struct InstanceFormView: View {
|
|||
|
||||
Section {
|
||||
Button(action: handleSave) {
|
||||
HStack {
|
||||
Spacer()
|
||||
ZStack {
|
||||
Text(isAddMode ? "Login" : "Save")
|
||||
.fontWeight(.semibold)
|
||||
.opacity(isLoading ? 0 : 1)
|
||||
if isLoading {
|
||||
ProgressView()
|
||||
.progressViewStyle(.circular)
|
||||
} else {
|
||||
Text(isAddMode ? "Login" : "Save")
|
||||
.fontWeight(.semibold)
|
||||
.tint(.white)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.buttonStyle(FlatPrimaryButtonStyle())
|
||||
.disabled(
|
||||
isLoading || serverURL.isEmpty
|
||||
|| (authMode == .credentials
|
||||
|
|
@ -330,6 +329,38 @@ struct InstanceFormView: View {
|
|||
}
|
||||
}
|
||||
|
||||
/// A full-width primary button style with a large hit target.
|
||||
///
|
||||
/// Defines its own appearance instead of relying on `.borderedProminent`, whose built-in
|
||||
/// press treatment springs/scales on release — on iOS 26 that read as the button's lower
|
||||
/// edge "collapsing" when the finger lifted. This style changes only the background opacity
|
||||
/// on press, with no `scaleEffect` and no spring, so the frame never moves.
|
||||
private struct FlatPrimaryButtonStyle: ButtonStyle {
|
||||
func makeBody(configuration: Configuration) -> some View {
|
||||
Background(configuration: configuration)
|
||||
}
|
||||
|
||||
private struct Background: View {
|
||||
let configuration: ButtonStyleConfiguration
|
||||
@Environment(\.isEnabled) private var isEnabled
|
||||
|
||||
var body: some View {
|
||||
configuration.label
|
||||
.font(.headline)
|
||||
.foregroundStyle(.white)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 14)
|
||||
.background(Color.accentColor.opacity(backgroundOpacity), in: Capsule())
|
||||
.contentShape(Capsule())
|
||||
}
|
||||
|
||||
private var backgroundOpacity: Double {
|
||||
if !isEnabled { return 0.35 }
|
||||
return configuration.isPressed ? 0.85 : 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#Preview("Add") {
|
||||
InstanceFormView(authService: .previewDefault, mode: .add)
|
||||
|
|
|
|||
Loading…
Reference in a new issue