SwiftUI - Размещение двух сборщиков рядом в HStack не изменяет размер сборщиков
Моя цель - расположить два сборщика рядом друг с другом горизонтально, чтобы каждый сборщик занимал половину ширины экрана. Представь себе UIPickerView
это соответствует ширине экрана и имеет два компонента одинаковой ширины - это то, что я пытаюсь воссоздать в SwiftUI.
Поскольку средства выбора в SwiftUI в настоящее время не допускают использование нескольких компонентов, для меня очевидной альтернативой было просто разместить два средства выбора внутри HStack
,
Вот пример кода из тестового проекта:
struct ContentView: View {
@State var selection1: Int = 0
@State var selection2: Int = 0
@State var integers: [Int] = [0, 1, 2, 3, 4, 5]
var body: some View {
HStack {
Picker(selection: self.$selection1, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
Picker(selection: self.$selection2, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
}
}
}
А вот и холст:
Подборщики не изменяют размеры, чтобы быть половиной ширины экрана, как я ожидал бы. Они сохраняют свой размер и вместо этого растягивают ширину представления контента, искажая ширину других элементов пользовательского интерфейса в процессе (как я узнал, когда попытался сделать это в моем другом проекте).
Я знаю, что я могу использовать UIViewRepresentable
чтобы получить эффект, который я хочу, но SwiftUI будет гораздо проще использовать, учитывая сложность того, для чего я пытаюсь использовать это.
Это ошибка, что два сборщика внутри HStack
неправильно изменяет их размер, или у пикеров в SwiftUI просто фиксированная ширина, которую нельзя изменить?
Обновить
С помощью GeometryReader
Мне удалось приблизиться к изменению размеров сборщиков, как я хочу, но не полностью.
Примечание: вы также можете достичь такого же несовершенного результата, не используя GeometryReader
просто установив рамку на каждом сборщике .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
,
Вот пример кода:
struct ContentView: View {
@State var selection1: Int = 0
@State var selection2: Int = 0
@State var integers: [Int] = [0, 1, 2, 3, 4, 5]
var body: some View {
GeometryReader { geometry in
HStack(spacing: 0) {
Picker(selection: self.$selection1, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
.frame(maxWidth: geometry.size.width / 2)
Picker(selection: self.$selection2, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
.frame(maxWidth: geometry.size.width / 2)
}
}
}
}
А вот и холст:
Сборщики в HStack с GeometryReader
Сборщики теперь ближе к желаемой внешности, но размеры все еще немного смещены, и теперь они накладываются друг на друга посередине.
3 ответа
Перекрытие в середине вы можете исправить, добавив модификатор clipped(). Что касается ширины, я вижу их обоих одинаково:
https://i.sta ck.imgur.com/9Un6I.png
struct ContentView: View {
@State var selection1: Int = 0
@State var selection2: Int = 0
@State var integers: [Int] = [0, 1, 2, 3, 4, 5]
var body: some View {
GeometryReader { geometry in
HStack(spacing: 0) {
Picker(selection: self.$selection1, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
.frame(maxWidth: geometry.size.width / 2)
.clipped()
.border(Color.red)
Picker(selection: self.$selection2, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
.frame(maxWidth: geometry.size.width / 2)
.clipped()
.border(Color.blue)
}
}
}
}
Начиная с iOS 15.5 (проверено на симуляторе), Xcode 13.4 в дополнение к добавлению .clipped() вам также необходимо добавить следующее расширение, чтобы предотвратить проблему перекрытия сенсорной области, упомянутую в комментариях из других ответов:
extension UIPickerView {
open override var intrinsicContentSize: CGSize {
return CGSize(width: UIView.noIntrinsicMetric , height: 150)
}
}
Просто поместите его перед структурой представления, где вы используете средство выбора.
Источник: TommyL на форуме Apple:https://developer.apple.com/forums/thread/687986?answerId=706782022#706782022 .
0
для предотвращения перекрытия в xcode13 просто добавьте
.compositingGroup()
затем добавьте
.clipped()