[英]UIViewRepresentable hidden behind SwiftUI View
I recently asked (and got a valid answer) to a question related to this issue.我最近询问(并得到了有效答案)与此问题相关的问题。
How do I get my UIViewRepresentable to correctly size for its content? 如何让我的 UIViewRepresentable 正确调整其内容的大小?
As I mentioned in the previous post, I want to use the awesome MultiSegmentPicker written by Yonat Sharon in my SwiftUI View.正如我在上一篇文章中提到的,我想在我的 SwiftUI 视图中使用 Yonat Sharon 编写的很棒的 MultiSegmentPicker。
https://github.com/yonat/MultiSelectSegmentedControl https://github.com/yonat/MultiSelectSegmentedControl
Implementing the answer showed that I'm not out of the woods, yet.实施答案表明我还没有走出困境。
Notice that the bar is behind the "bottom" text view请注意,该栏位于“底部”文本视图的后面
In my non-demo view it is completely hidden behind other views - so it's not visible at all.在我的非演示视图中,它完全隐藏在其他视图后面 - 所以它根本不可见。
I understand this is a constraints issue, and Xcode view debugging helpfully confirms:我知道这是一个约束问题,并且 Xcode 查看调试有助于确认:
runtime: Layout Issues: Position is ambiguous for MultiSelectSegmentedControl.
运行时:布局问题:Position 对于 MultiSelectSegmentedControl 不明确。
Where do I address this problem?我在哪里解决这个问题? Is it in the UIViewRepresentable which is not behaving as I would expect?
是否在 UIViewRepresentable 中的行为不像我预期的那样? Since the package has been around for years, and pure UIKit code does not encounter this issue, I'm pretty sure that the issue is in the UIViewRepresentable code.
由于 package 已经存在多年,纯 UIKit 代码不会遇到此问题,我很确定问题出在 UIViewRepresentable 代码中。
In the init for MultiSelectSegmentedControl is the following setup code:在 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"
}
In the MultiSegmentPicker: UIViewRepresentable 's init I find the following code related to constraints:在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
}
Also, the segment views MultiSelectSegment: UIView use this code:此外,分段视图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"
}
Here is the code that demonstrates the problem shown above:这是演示上述问题的代码:
var body: some View {
VStack(alignment: .center) {
Text("top")
Spacer()
MultiSegmentPicker(
selectedSegmentIndexes: $selectedSegmentIndexes,
items: ["First", "Second", "Third", "Done"]
).fixedSize()
Text("bottom")
}
}
}
What I expected from this code is that the bar with "First", "Second", etc. would be centered on the bottom, not pushed to the trailing edge, and that it would be above not behind the Text View displaying "bottom"我对这段代码的期望是,带有“First”、“Second”等的栏将位于底部的中心,而不是推到后缘,并且它会在显示“底部”的文本视图的上方而不是后面
=== EDIT === Here's the view with the spacer removed and the.center alignment removed as well. === 编辑 === 这是移除了垫片和.center alignment 的视图。
It might be helpful to see the difference...看到差异可能会有所帮助...
=== EDIT 2 == === 编辑 2 ==
I want to show a little more "unexpected" behavior.我想表现出更多“意外”的行为。 Once you think about it, it isn't unexpected at all.
仔细想想,一点也不意外。 The Multiselector was positioned correctly, but hidden by the bigger view.
多选器的位置正确,但被更大的视图隐藏了。 When I added a regular Picker() object after the Multiselector, the multiselector peeks through... But these two pictures explain a lot:
当我在 Multiselector 之后添加一个常规 Picker() object 时,multiselector 会窥视...但这两张图片说明了很多:
== Edit 3 == == 编辑 3 ==
Yonat has fixed this bug, it works as expected now! Yonat 已经修复了这个错误,它现在可以正常工作了! (thanks!)
(谢谢!)
The problem seemed to be with intrinsicContentSize
.问题似乎出在
intrinsicContentSize
。 I changed in in version 2.3.3 of the control, and now fixedSize()
works fine.我在控件的 2.3.3 版本中进行了更改,现在
fixedSize()
工作正常。
The alignment: .center is centering the leading edge of your picker, remove that from VSTack. alignment:.center 将拾取器的前缘居中,将其从 VSTack 中移除。
remove the Spacer() and it won't be behind, but since it's set up as a stackView SwiftUI won't automatically position it in relation to other elements.删除 Spacer() 并且它不会落后,但由于它设置为 stackView SwiftUI 不会自动 position 与其他元素相关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.