У меня есть реализация, которая на 90 % соответствует этому, но я нажимаю какое-то очень странное поведение при попытке установить ширину и высоту представлений.
Стоит отметить, что я не могу использовать .infinity для ширины, поскольку это представление должно иметь фиксированная ширина. Кроме того, мне нужно ориентироваться на iOS 13, поэтому любое решение, включающее более новые API для iOS 14+, я не могу использовать.
Вот код, который у меня есть:
Код: Выделить всё
import SwiftUI
// MARK: - Testview
struct Testview: View {
// MARK: Internal
var body: some View {
HStack {
CircleView(number: "2", maxSize: maxSize)
CircleView(number: "24", maxSize: maxSize)
CircleView(number: "246", maxSize: maxSize)
}
.background(Color.orange)
.onPreferenceChange(CircleSizePreferenceKey.self, perform: { value in
maxSize = value
})
}
// MARK: Private
@State private var maxSize: CGSize = .zero
}
#Preview {
Testview()
.environment(\.sizeCategory, .extraLarge)
}
// MARK: - CircleView
struct CircleView: View {
// MARK: Lifecycle
init(number: String?, maxSize: CGSize) {
if
let number,
!number.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.number = number
} else {
self.number = " " // To preserve the size since an empty string results in a default sized circle (16.0 pts)
}
self.maxSize = maxSize
}
// MARK: Internal
var number: String
var maxSize: CGSize
var body: some View {
Text(number)
.padding(8.0)
.background(
GeometryReader { geometry in
Color.clear
.preference(
key: CircleSizePreferenceKey.self,
value: geometry.size
)
}
)
.frame(width: maxSize.width)
.background(
Circle()
.fill(Color.white)
.frame(width: maxSize.width, height: maxSize.height)
.background(
Circle()
.stroke(.black.opacity(0.15), lineWidth: 1.5)
)
)
}
}
// MARK: - CircleSizePreferenceKey
private struct CircleSizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
let newSize = nextValue()
let maxSize = max(value.width, value.height, newSize.width, newSize.height)
value = CGSize(width: maxSize, height: maxSize)
}
}
[img]https:/ /i.sstatic.net/tCVif39y.png[/img]
Проблема в том, что родитель не знает, какой высоты он должен быть, поэтому верх и низ круга представления выходят за пределы родительского элемента.
Как только я устанавливаю высоту кадра в CircleView, круговые представления сжимаются до 16 точек.

Я отладил размер представления и, как указано выше, при указании только ширины maxSize возвращается как (110.666, 110.666), но при указании высоты размер возвращается как (16.0, 16.0).
Может ли кто-нибудь помочь с этим и сообщить мне, есть ли что-то, что я делаю неправильно, или есть ли лучший способ добиться того, чего я пытаюсь достичь?
Подробнее здесь: https://stackoverflow.com/questions/784 ... ew-swiftui
Мобильная версия