Bei der Bildschaltfläche fällt mir auf, dass der Abstandshalter nicht funktioniert, wenn die Größe unendlich viele sich wiederholende Dezimalstellen enthält (z. B. .666666...). Beispiel:
Code: Select all
public var body: some View {
// Spacers don't work
let width: CGFloat = 18.0 + (2.0 / 3.0)
let height: CGFloat = 26.0 + (2.0 / 3.0)
Image(uiImage: uiImage)
.renderingMode(.template)
.frame(width: width, height: height)
}

Wenn ich jedoch die Zahlen runde, funktioniert es:
Code: Select all
// this works
.frame(width: width.rounded(), height: height.rounded())
Code: Select all
// this also works
.frame(width: width.rounded() + .pi, height: height.rounded() + .pi)

Unter iOS 18 hat alles gut funktioniert. Ich bin mir nicht sicher, wie ich meine App unter iOS 26 am besten reparieren kann. Ich kann sicherlich „round()“ aufrufen, aber es fühlt sich bei vielen Vermutungen fragil an.
Hier ist ein Minimum Repro, mit der Sie herumspielen können:
Code: Select all
import SwiftUI
struct ContentView: View {
@State var text: String = ""
var body: some View {
NavigationStack {
List {
TextField("Click Me", text: $text)
Text("Hello, world!").font(Font.system(size: 32))
Text("Hello, world!").font(Font.system(size: 32))
Text("Hello, world!").font(Font.system(size: 32))
Text("Hello, world!").font(Font.system(size: 32))
Text("Hello, world!").font(Font.system(size: 32))
}
.toolbar {
ToolbarItemGroup(placement: .topBarLeading) {
Button {
} label: {
Text("Toggle")
}
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
keyboardButtons
}
}
}
.navigationTitle("Hello")
}
@ViewBuilder
private var keyboardButtons: some View {
HStack {
SUITextButton("Button") {}
Spacer()
SUIImageButton(
image: UIImage(
systemName: "envelope",
withConfiguration: UIImage.SymbolConfiguration(pointSize: 32, weight: .regular, scale: .small)
)!,
enabled: true
) {}
Spacer()
SUIImageButton(
image: UIImage(
systemName: "envelope",
withConfiguration: UIImage.SymbolConfiguration(pointSize: 32, weight: .regular, scale: .small)
)!,
enabled: true
) {}
Spacer()
SUITextButton("Button") {}
}
}
}
#Preview {
ContentView()
}
public struct SUITextButton: View {
private let title: String
private let action: () -> Void
private let enabled: Bool
public init(_ title: String, enabled: Bool = true, action: @escaping () -> Void) {
self.title = title
self.enabled = enabled
self.action = action
}
public var body: some View {
Button(title, action: action)
}
}
public struct SUIImageButton: View {
public init(image: UIImage, enabled: Bool, action: @escaping () -> Void) {
self.image = image
self.enabled = enabled
self.action = action
}
private let image: UIImage
private let enabled: Bool
private let action: () -> Void
public var body: some View {
Button(action: action) {
SUIImage(
uiImage: image,
// Since it's inside of a button, it will be blue when enabled, and gray when disabled.
rendering: .systemTint)
}
}
}
public struct SUIImage: View {
public enum Rendering {
// template mode
// In buttons, blue if enabled, gray if disabled
// Otherwise (e.g. text), black if light mode, white if dark mode
case systemTint
// template mode + foreground color (e.g. magic item with overlay)
case customColor(color: UIColor)
// original mode (e.g. magic item without overlay)
case original
}
private let uiImage: UIImage
private let rendering: Rendering
public init(uiImage: UIImage, rendering: Rendering) {
self.uiImage = uiImage
self.rendering = rendering
}
public var body: some View {
let width: CGFloat = 18.0 + (2.0 / 3.0)
let height: CGFloat = 26.0 + (2.0 / 3.0)
Image(uiImage: uiImage)
.renderingMode(.template)
.frame(width: width.rounded() + .pi, height: height.rounded() + .pi)
}
}
Mobile version