如何将图像垂直对齐到某些文本第一行的中心?
Posted
技术标签:
【中文标题】如何将图像垂直对齐到某些文本第一行的中心?【英文标题】:How can I vertically align an image to the center of the first line of some text? 【发布时间】:2020-07-23 08:09:25 【问题描述】:我有一个要点和一些长的多行文本。我希望项目符号点与第一行文本的中心对齐。显然,如果字符串足够短且一行长,那么两个视图会自动居中对齐。我对文本长度超过一行的情况感兴趣。
var body: some View
HStack
Image(systemName: "circle.fill")
.font(.system(size: 8))
Text("Insert really long multiline string that wraps.")
这可能吗?
更新 1:
将 HStack 对齐设置为 top 将图像的顶部与文本的顶部对齐,像这样...
var body: some View
HStack(alignment: .top)
Image(systemName: "circle.fill")
.font(.system(size: 8))
Text("This is really really really really really really really really really really really really really really really really really really really really really really really really long string.")
更新 2:
我能想到的唯一选择是this,除了这是 UIKit...
// Aligns the icon to the center of a capital letter in the first line
let offset = label.font.capHeight / 2.0
// Aligns the icon to the center of the whole line, which is different
// than above. Especially with big fonts this makes a visible difference.
let offset = (label.font.ascender + label.font.descender) / 2.0
let constraints: [NSLayoutConstraint] = [
imageView.centerYAnchor.constraint(equalTo: label.firstBaselineAnchor, constant: -offset),
imageView.trailingAnchor.constraint(equalTo: label.leadingAnchor, constant: -10)
]
NSLayoutConstraint.activate(constraints)
【问题讨论】:
【参考方案1】:这是一个基于自定义对齐的解决方案。使用 Xcode 11.4 / ios 13.4 测试
extension VerticalAlignment
private enum XAlignment : AlignmentID
static func defaultValue(in d: ViewDimensions) -> CGFloat
return d[VerticalAlignment.top]
static let xAlignment = VerticalAlignment(XAlignment.self)
struct DemoAlignFirstLine: View
var body: some View
HStack(alignment: .xAlignment)
Image(systemName: "circle.fill")
.font(.system(size: 8))
.alignmentGuide(.xAlignment) $0.height / 2.0
ZStack(alignment: .topLeading)
// invisible anchor, should be of same font as text
Text("X").foregroundColor(.clear)
.alignmentGuide(.xAlignment) $0.height / 2.0
// main text
Text("This is really really really really really really really really really really really really really really really really really really really really really really really really long string.")
【讨论】:
谢谢。这与文本基线对齐,而不是中心。【参考方案2】:假设所有文本行的基线之间的高度/距离都相同,我们可以受益于提供给.alignmentGuide
的尺寸具有第一个和最后一个基线,并获得第一个的高度(实际上, any) 线,只需从视图高度中减去最后一条基线和第一条基线之间的距离即可。
重用@Asperi提供的答案条款,这是不需要引入ZStack/fake view的解决方案:
extension VerticalAlignment
private enum XAlignment : AlignmentID
static func defaultValue(in d: ViewDimensions) -> CGFloat
return d[VerticalAlignment.top]
static let xAlignment = VerticalAlignment(XAlignment.self)
struct DemoAlignFirstLine: View
var body: some View
HStack(alignment: .xAlignment)
Image(systemName: "circle.fill")
.font(.system(size: 8))
.alignmentGuide(.xAlignment) $0.height / 2.0
// main text
Text("This is really really really really really really really really really really really really really really really really really really really really really really really really long string.")
.alignmentGuide(.xAlignment)
($0.height - ($0[.lastTextBaseline] - $0[.firstTextBaseline])) / 2
【讨论】:
【参考方案3】:iOS 14 你可以使用Label。
Label
Text("This is really really really really really really really really really really really really really really really really really really really really really really really really long string.")
icon:
Image(systemName: "circle.fill")
.font(.system(size: 8))
【讨论】:
以上是关于如何将图像垂直对齐到某些文本第一行的中心?的主要内容,如果未能解决你的问题,请参考以下文章