Что касается кнопки изображения, я заметил, что если размер содержит бесконечные повторяющиеся десятичные знаки (например, .666666...), то разделитель не работает. Например:
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)
}
Смотрите картинку:

Однако, если я округлю числа, это сработает:
// this works
.frame(width: width.rounded(), height: height.rounded())
Я подозреваю, что это не имеет никакого отношения к бесконечно повторяющимся десятичным знакам, поскольку CGFloat является двоичным и не может точно представлять 2/3. Поэтому из любопытства я попробовал .pi, но он все равно работал. Так что иррациональные числа — это нормально. Это становится странно.
// this also works
.frame(width: width.rounded() + .pi, height: height.rounded() + .pi)

В iOS 18 все работало нормально. Я не уверен, как лучше всего исправить свое приложение на iOS 26. Я, конечно, могу вызвать rounded(), но из-за большого количества догадок он кажется хрупким.
Вот минимальный репродукция, с которой можно поиграть:
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)
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... s-infinite
Мобильная версия