隐藏在 SwiftUI View 后面的 UIViewRepresentable
UIViewRepresentable hidden behind SwiftUI View
我最近问了一个与此问题相关的问题(并得到了有效答案)。
正如我在前面提到的post,
我想在我的 SwiftUI 视图中使用由 Yonat Sharon 编写的很棒的 MultiSegmentPicker。
https://github.com/yonat/MultiSelectSegmentedControl
实施答案表明我还没有走出困境。
注意栏在 "bottom" 文本视图后面
在我的非演示视图中,它完全隐藏在其他视图后面 - 所以它根本不可见。
我知道这是一个约束问题,Xcode 查看调试有助于确认:
runtime: Layout Issues: Position is ambiguous for
MultiSelectSegmentedControl.
我在哪里解决这个问题?它在 UIViewRepresentable 中是否没有像我预期的那样表现?由于这个包已经存在多年,纯 UIKit 代码没有遇到这个问题,我很确定问题出在 UIViewRepresentable 代码中。
在 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 的初始化中,我找到了以下与约束相关的代码:
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" 等的条形图将位于底部的中心,而不是被推到后缘,并且它将是 在 之上而不是 在 文本视图显示 "bottom"
之后
=== 编辑 ===
这是移除了垫片并移除了 .center 对齐的视图。
查看差异可能会有所帮助...
=== 编辑 2 ==
我想展示更多 "unexpected" 行为。仔细一想,一点也不意外。 Multiselector 定位正确,但被更大的视图隐藏了。当我在多选器之后添加一个常规的 Picker() 对象时,多选器会通过...
不过这两张图说明了很多:
== 编辑 3 ==
Yonat 已修复此错误,现在可以正常使用了! (谢谢!)
对齐方式:.center 使选择器的前缘居中,将其从 VSTack 中移除。
删除 Spacer() 它不会落后,但由于它被设置为 stackView SwiftUI 不会自动相对于其他元素定位它。
问题似乎出在 intrinsicContentSize
。我在控件的 2.3.3 版本中进行了更改,现在 fixedSize()
工作正常。
我最近问了一个与此问题相关的问题(并得到了有效答案)。
正如我在前面提到的post, 我想在我的 SwiftUI 视图中使用由 Yonat Sharon 编写的很棒的 MultiSegmentPicker。
https://github.com/yonat/MultiSelectSegmentedControl
实施答案表明我还没有走出困境。
注意栏在 "bottom" 文本视图后面
在我的非演示视图中,它完全隐藏在其他视图后面 - 所以它根本不可见。
我知道这是一个约束问题,Xcode 查看调试有助于确认:
runtime: Layout Issues: Position is ambiguous for MultiSelectSegmentedControl.
我在哪里解决这个问题?它在 UIViewRepresentable 中是否没有像我预期的那样表现?由于这个包已经存在多年,纯 UIKit 代码没有遇到这个问题,我很确定问题出在 UIViewRepresentable 代码中。
在 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 的初始化中,我找到了以下与约束相关的代码:
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" 等的条形图将位于底部的中心,而不是被推到后缘,并且它将是 在 之上而不是 在 文本视图显示 "bottom"
之后=== 编辑 === 这是移除了垫片并移除了 .center 对齐的视图。
查看差异可能会有所帮助...
=== 编辑 2 ==
我想展示更多 "unexpected" 行为。仔细一想,一点也不意外。 Multiselector 定位正确,但被更大的视图隐藏了。当我在多选器之后添加一个常规的 Picker() 对象时,多选器会通过... 不过这两张图说明了很多:
== 编辑 3 ==
Yonat 已修复此错误,现在可以正常使用了! (谢谢!)
对齐方式:.center 使选择器的前缘居中,将其从 VSTack 中移除。
删除 Spacer() 它不会落后,但由于它被设置为 stackView SwiftUI 不会自动相对于其他元素定位它。
问题似乎出在 intrinsicContentSize
。我在控件的 2.3.3 版本中进行了更改,现在 fixedSize()
工作正常。