当前位置: 首页 > 知识库问答 >
问题:

swift中文本的垂直对齐方式

汪晨
2023-03-14

如图所示,我有代码在屏幕上绘制文本。textalign函数仅支持水平对齐。现在,我要添加对垂直对齐的支持。有人能帮我一下吗?

代码

func textAlign(_ horizonalAlign: String, _ verticalAlign: String? = nil){
    settings.textAlignment = horizonalAlign
}

func text(_ str: String, _ x: CGFloat, _ y: CGFloat, _ x2: CGFloat? = nil, _ y2: CGFloat? = nil) {
    let fontSizeWidthRatio: CGFloat = 1.8
    let paragraphStyle = NSMutableParagraphStyle()
    
    var align: NSTextAlignment!
    switch settings.textAlignment {
    case LEFT:
        align = .left
    case RIGHT:
        align = .right
    case CENTER:
        align = .center
    default:
        align = .left
    }
    paragraphStyle.alignment = align
    
    let attributes: [NSAttributedString.Key: Any] = [
        .paragraphStyle: paragraphStyle,
        .font: UIFont(name: settings.textFont, size: settings.textSize)!,
        .foregroundColor: settings.fill.uiColor(),
        .strokeWidth: -settings.strokeWeight,
        .strokeColor: settings.stroke.uiColor(),
        .baselineOffset: y,
    ]
    
    if x2 == nil {
        str.draw(at: CGPoint(x: x, y: y), withAttributes: attributes)
    }else{
        str.draw(with: CGRect(x: x, y: y, width: (x2 != nil) ? x2! : width, height: (y2 != nil) ? y2! : height), options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
    }
}

共有1个答案

诸超
2023-03-14

正如Larme所建议的,你应该直接发布你的代码,这样更容易阅读,而且...复制粘贴:d

所以我的意见是,自己根据一个自定义枚举来计算字符串的rect:

    enum VerticalAlign {
    case top
    case center
    case bottom
}

当然,这意味着如果从cgpoint中绘制,则只能在cgrect中绘制,则不能使用这种对齐方式。

你的功能会变成这样:

    func text(_ str: String, _ x: CGFloat, _ y: CGFloat, _ x2: CGFloat? = nil, _ y2: CGFloat? = nil, _ verticalAlign: VerticalAlign) {

    // Add your paragrapheStyle and horizontal alignment here
    // ...
    // ...
    // ... and set your attributes
    let attributes: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 18.0),
        .foregroundColor: UIColor.red
    ]
    let hardcodedHeightValue: CGFloat = 20.0
    
    // Vertical alignment can be only used if you draw in rect (so in your example, its only if you have a width)
    if let width = x2 {
        let height = y2 ?? hardcodedHeightValue
        let size = str.size(withAttributes: attributes)
        let centeredRect: CGRect
        switch verticalAlign {
        case .top:
            centeredRect = CGRect(x: x,
                                  y: y,
                                  width: width,
                                  height: size.height)
        case .center:
            centeredRect = CGRect(x: x,
                                  y: y + height * 0.5 - size.height * 0.5,
                                  width: width,
                                  height: size.height)
        case .bottom:
            centeredRect = CGRect(x: x,
                                  y: y + height - size.height,
                                  width: width,
                                  height: size.height)
        }
        str.draw(in: centeredRect, withAttributes: attributes)

    } else {
        str.draw(at: CGPoint(x: x, y: y), withAttributes: attributes)
    }
}
 类似资料:
  • 问题内容: 下面的代码(也可以在JSFiddle上作为演示使用没有将文本放在中间,正如我理想中的那样。即使使用属性,我也找不到任何方法可以使文本垂直居中。我怎样才能做到这一点? 问题答案: 创建一个用于文本内容的容器,也许是。 JSFiddle

  • 问题内容: 目标:纯Canvas上的Android> = 1.6。 假设我想编写一个函数,该函数将绘制一个(宽度,高度)大的红色矩形,然后在其中绘制一个黑色的 Hello World 文本。我希望文本在视觉上位于矩形的中心。因此,让我们尝试: 现在,我不知道要在drawText的参数中加上标记的内容,即我不知道如何垂直对齐文本。 就像是 ???? = topLeftY + height / 2 +

  • 我想使用flexbox来垂直对齐 中的一些内容,但没有取得很大的成功。 我在网上查了一下,很多教程实际上都使用了包装器div,它从父级的flex设置中获得,但我想知道是否可以去掉这个附加元素? 我选择在此实例中使用flexbox,因为列表项高度将是动态的。 null null

  • 垂直对齐 1. grid-template-areas 属性值保持换行,并使用空格保持每列垂直对齐。 例如: .foo { grid-template-areas: "header header" "nav main" "footer ...."; } 2. grid、grid-template

  • 问题内容: 我试图找到最有效的方法来使div对齐文本。我尝试了几件事,但似乎都没有用。 问题答案: 对于CSS 2浏览器,可以使用/ 来使内容居中。 jSFiddle提供了一个示例: 可以将旧浏览器(Internet Explorer 6/7)的hack合并为样式,并用于从较新的浏览器中隐藏样式:

  • 问题内容: 我试图在一个JPanel中垂直对齐(居中)两个JLabel。 我尝试使用setAligmentY()失败。这两个标签始终显示在JPanel的顶部。 UPD:标签应该像使用FlowLayout那样彼此相邻放置,但应位于JPanel的中间。 问题答案: 使用具有默认约束的。这是一个小的演示代码: