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

DPM*_*itu 15 swiftui

我有一个要点和一些长的多行文本。我希望项目符号点与第一行文本的中心对齐。显然,如果字符串足够短并且一行长,那么两个视图会自动居中对齐。我对文本长度超过一行的情况感兴趣。

var body: some View {
    HStack {
        Image(systemName: "circle.fill")
            .font(.system(size: 8))
        Text("Insert really long multiline string that wraps.")
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?

更新1:

将 HStack 对齐设置为顶部会将图像的顶部与文本的顶部对齐,如下所示...

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.")
    }
}
Run Code Online (Sandbox Code Playgroud)

图片1

更新2:

我能想到的唯一选择是这样的除了这是 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)
Run Code Online (Sandbox Code Playgroud)

Dan*_*eel 13

在 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))
}
Run Code Online (Sandbox Code Playgroud)


Gri*_*tin 5

假设所有文本行的基线之间应该具有相等的高度/距离,我们可以从以下事实中受益:尺寸提供了.alignmentGuide第一个和最后一个基线,并且只需减去第一行(实际上是任何)的高度即可最后一条基线和第一条基线与视图高度之间的距离。

重用@Asperi提供的答案的条款,这是不需要引入ZStack/fake视图的解决方案:

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
                }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Asp*_*eri 3

这是一个基于自定义对齐的解决方案。使用 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.")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)