如何将图像垂直对齐到某些文本第一行的中心?

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))

【讨论】:

以上是关于如何将图像垂直对齐到某些文本第一行的中心?的主要内容,如果未能解决你的问题,请参考以下文章

如何将箭头图标垂直对齐到中心

如何左对齐和垂直对齐标题中的图像并将文本水平保持在div的中心[重复]

将元素水平和垂直对齐到页面的中心[重复]

如何垂直对齐段落中心

使 JLabel 文本与中心垂直对齐

浮动后对齐中心项目