Я недавно задал (и получил действительный ответ) вопрос, связанный с этой проблемой.
Как мне получить свой UIViewRepresentable для правильного размера его содержимого?
Как я упоминал в предыдущем посте, я хочу использовать удивительный MultiSegmentPicker, написанный Йонатом Шароном. в моем SwiftUI View.
https://github.com/yonat/MultiSelectSegmentedControl
Реализация ответа показала, что я еще не в лесу.
Обратите внимание, что полоса находится за «нижним» текстовым представлением
В моем не демонстрационном представлении она полностью скрыта за другими представлениями - так что он вообще не виден.
Я понимаю, что это проблема с ограничениями, и отладка представления XCode полезно подтверждает:
runtime: Проблемы с компоновкой: Положение неоднозначно для MultiSelectSegmentedControl.
Где мне решить эту проблему? Это в UIViewRepresentable, который не ведет себя, как я ожидал? Поскольку пакет существует уже много лет, и чистый код UIKit не сталкивается с этой проблемой, я почти уверен, что проблема в коде UIViewRepresentable.
В init для MultiSelectSegmentedControl есть следующий код установки:
private func setup() {
addConstrainedSubview(borderView, constrain: .top, .bottom, .left, .right)
addConstrainedSubview(stackView, constrain: .top, .bottom)
constrain(stackView, at: .left, to: borderView, diff: 1)
constrain(stackView, at: .right, to: borderView, diff: -1)
clipsToBounds = true
stackView.distribution = .fillEqually
borderWidth = { borderWidth }()
borderRadius = { borderRadius }()
tintColorDidChange()
borderView.isUserInteractionEnabled = false
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTap)))
accessibilityIdentifier = "MultiSelectSegmentedControl"
}
В MultiSegmentPicker: UIViewRepresentable init Я нахожу следующий код, связанный с ограничениями:
public init(
selectedSegmentIndexes: Binding<IndexSet>,
items: [Any],
allowsMultipleSelection: Bool? = nil,
borderWidth: CGFloat? = nil,
borderRadius: CGFloat? = nil,
isVertical: Bool? = nil,
isVerticalSegmentContents: Bool? = nil,
selectedBackgroundColor: UIColor? = nil
) {
_selectedSegmentIndexes = selectedSegmentIndexes
uiView = MultiSelectSegmentedControl(items: items)
uiView.translatesAutoresizingMaskIntoConstraints = false
uiView.allowsMultipleSelection =? allowsMultipleSelection
uiView.borderWidth =? borderWidth
uiView.borderRadius =? borderRadius
uiView.isVertical =? isVertical
uiView.isVerticalSegmentContents =? isVerticalSegmentContents
uiView.selectedBackgroundColor =? selectedBackgroundColor
}
Кроме того, представления сегментов MultiSelectSegment: UIView используйте этот код:
private func setup() {
addConstrainedSubview(stackView, constrain: .topMargin, .bottomMargin, .leftMargin, .rightMargin)
layoutMargins = UIEdgeInsets(top: 7, left: 7, bottom: 7, right: 7)
stackView.spacing = layoutMargins.left
stackView.isUserInteractionEnabled = false
stackView.alignment = .center
isAccessibilityElement = true
accessibilityTraits = [.button]
accessibilityIdentifier = "MultiSelectSegment"
}
Вот код, который демонстрирует проблему, показанную выше:
var body: some View {
VStack(alignment: .center) {
Text("top")
Spacer()
MultiSegmentPicker(
selectedSegmentIndexes: $selectedSegmentIndexes,
items: ["First", "Second", "Third", "Done"]
).fixedSize()
Text("bottom")
}
}
}
Что я ожидал от этого кода, так это то, что столбец с «First», «Second» и т. Д. c. будет располагаться по центру снизу, а не сдвигаться к задней кромке, и что он будет выше , а не позади в текстовом представлении, отображающем «низ»
=== РЕДАКТИРОВАТЬ === Вот вид со снятой проставкой и выравниванием .center.
Может быть полезно увидеть разницу ...
=== РЕДАКТИРОВАТЬ 2 ==
Я хочу показать немного более «неожиданное» поведение. Когда вы думаете об этом, это совсем не неожиданно. Мультиселектор был расположен правильно, но скрыт от большого взгляда. Когда после Multiselector я добавил обычный объект Picker (), мультиселектор заглядывает сквозь ... Но эти две картинки многое объясняют:
== Редактировать 3 ==
Йонат исправил эту ошибку, теперь она работает, как и ожидалось! (спасибо!)