在选取器中对齐视图
Posted
技术标签:
【中文标题】在选取器中对齐视图【英文标题】:Align views in Picker 【发布时间】:2021-06-14 23:34:58 【问题描述】:如何将Color
视图与文本对齐成一条直线?
看起来像这样(文本对齐前导):
█ 红色 █ 绿色 █ 蓝色
或者这个(文本居中对齐):
█ 红色 █ 绿色 █ 蓝色
当前代码:
struct ContentView: View
@State private var colorName: Colors = .red
var body: some View
Picker("Select color", selection: $colorName)
ForEach(Colors.allCases) color in
HStack
color.asColor.aspectRatio(contentMode: .fit)
Text(color.rawValue)
enum Colors: String, CaseIterable, Identifiable
case red
case green
case blue
var id: String rawValue
var asColor: Color
switch self
case .red: return .red
case .green: return .green
case .blue: return .blue
结果(未正确对齐):
没有Picker
,我发现可以使用alignmentGuide(_:computeValue:)
来实现结果。但是,这需要在 Picker
中。
尝试:
VStack(alignment: .custom)
ForEach(Colors.allCases) color in
HStack
color.asColor.aspectRatio(contentMode: .fit)
.alignmentGuide(.custom) d in
d[.leading]
Text(color.rawValue)
.frame(maxWidth: .infinity)
.fixedSize()
.frame(height: 50)
/* ... */
extension HorizontalAlignment
struct CustomAlignment: AlignmentID
static func defaultValue(in context: ViewDimensions) -> CGFloat
return context[HorizontalAlignment.leading]
static let custom = HorizontalAlignment(CustomAlignment.self)
尝试结果:
【问题讨论】:
【参考方案1】:可能的解决方案是对使用视图首选项计算的最大标签应用的标签使用动态宽度。
这是一个演示。使用 Xcode 13beta / ios15 测试
注意:ViewWidthKey
取自我的另一个答案https://***.com/a/63253241/12299030
struct ContentView: View
@State private var colorName: Colors = .red
@State private var maxWidth = CGFloat.zero
var body: some View
Picker("Select color", selection: $colorName)
ForEach(Colors.allCases) color in
HStack
color.asColor.aspectRatio(contentMode: .fit)
Text(color.rawValue)
.background(GeometryReader
Color.clear.preference(key: ViewWidthKey.self,
value: $0.frame(in: .local).size.width)
)
.onPreferenceChange(ViewWidthKey.self)
self.maxWidth = max($0, maxWidth)
.frame(minWidth: maxWidth, alignment: .leading)
【讨论】:
完美运行!我毫无疑问地知道,如果有人能解决它……那就是 Asperi :)【参考方案2】:我认为这应该对齐您的文本并解决您的问题。
struct ContentView: View
@State private var colorName: Colors = .red
var body: some View
Picker("Select color", selection: $colorName)
ForEach(Colors.allCases) color in
HStack()
color.asColor.aspectRatio(contentMode: .fit)
Text(color.rawValue)
.frame(width: 100, height: 30, alignment: .leading)
一个简单的.frame
修饰符将解决这些问题,如果您不想在选择器或列表视图方面使事情复杂化,请尝试将您的文本框在一起或使用Label
。
如果您确实继续使用此解决方案,请尝试根据您的要求尝试使用 width
和 height
,看看您是否需要 .leading
或 .trailing
对齐
【讨论】:
我的问题的原始编辑使用Label
,因为我不知道有人会如何解决问题,所以我切换了它。虽然这主要解决了这个问题,但最好有一些居中的东西并使用对齐指南之类的东西,所以我不需要硬编码任何尺寸。实际上我有比这更多的项目,这只是一个最小的例子。不过还是谢谢你的回答!基本上选择器中最宽的项目会保留,其他所有内容都与此对齐。
如果你想要居中的项目而不是前导,使用框架,框架的作用是将整个文本保持在高度 * 宽度空间内,所以我要做的是看看最大的颜色是什么您拥有的长度并基于该长度设置帧大小。我很少使用对齐指南,因为我不需要它们,但也许其他人可以帮助你。
问题是它应该适应不同的字体大小等:/
添加了alignmentGuide
的尝试,在不使用Picker
时有效。以上是关于在选取器中对齐视图的主要内容,如果未能解决你的问题,请参考以下文章