Одинаковый размер дочерних представлений в представлении стека SwiftUIIOS

Программируем под IOS
Ответить
Anonymous
 Одинаковый размер дочерних представлений в представлении стека SwiftUI

Сообщение Anonymous »

Я пытаюсь создать представление, в котором у меня есть текстовые представления в HStack с круглым фоном, где размер каждого дочернего элемента зависит от самого большого дочернего элемента в стеке. Цель состоит в том, чтобы все представления имели одинаковую ширину и высоту во всех категориях размеров.
У меня есть реализация, которая на 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»