SpriteKit:有没有办法根据其基线将 SKLabelNode 居中

2023-12-08

一个标签有四种不同的verticalAlignmentMode: .Baseline, .Bottom, .Center and .Top.

我希望标签根据其基线在其位置上居中。.Center对我不起作用,因为框架的底部不是文本的基线,而是最低字母的底部(例如“y”)。

我也尝试过使用.Baseline并从 y 位置减去框架高度的一半,但这也不起作用,并且会导致与.Center.

我试图居中的标签中的文本是“播放!”。将模式设置为“.Center”会使文本略高于我想要的位置,这是非常明显的。将文本更改为“Pla!”解决了问题,因为“y”被删除,并且没有任何字符悬挂在基线以下(不过,我显然不能将其作为解决方案)。

我想要一个解决这个问题的建议 - 也许有某种方法可以获取基线的位置?谢谢!


所以我遇到了同样的问题并在以下人员的帮助下这个问题和答案我找到了一个不错的解决方案。

我想将标签节点的文本与自定义按钮节点(包裹在形状节点中以绘制轮廓的标签节点)对齐。

我还想将切换(开/关)按钮与标签节点的基线对齐,并使用与标签中文本的 xHeight 相同的高度。

Aligning labels, buttons and shapes The red lines show that all labels & buttons are properly aligned.

因此,为了做到这一点,我做了以下工作。

我创建了一个 Font 类,可用于从fontName and fontSize in a SKLabelNode.

在内部它将创建一个NSFont(macOS) 或UIFont(iOS)。并设置ascender、descender属性。为了方便起见,还有一个 getter 可以返回字体的最大可能高度。

import Foundation

#if os(macOS)
import Cocoa
#endif

#if os(iOS)
import UIKit
#endif

enum FontError: LocalizedError {
    case invalidFont(String, CGFloat)

    var errorDescription: String? {
        switch self {
        case .invalidFont(let name, let size):
            return "Could not create font with name \(name) and size: \(size)"
        }
    }
}

class Font {
    private(set) var name: String
    private(set) var size: CGFloat

    private(set) var ascender: CGFloat
    private(set) var descender: CGFloat
    private(set) var xHeight: CGFloat

    var maxHeight: CGFloat {
        return self.ascender + fabs(self.descender)
    }

    init(name: String, size: CGFloat) throws {
        // check if font can be created, otherwise crash
        // set ascender, descender, etc...
        #if os(macOS)
        guard let font = NSFont(name: name, size: size) else {
            throw FontError.invalidFont(name, size)
        }

        self.ascender = font.ascender
        self.descender = font.descender
        self.xHeight = font.xHeight
        #endif

        #if os(iOS)
        guard let font = UIFont(name: name, size: size) else {
            throw FontError.invalidFont(name, size)
        }
        self.ascender = font.ascender
        self.descender = font.descender
        self.xHeight = font.xHeight
        #endif

        self.name = name
        self.size = size
    }
}

然后,我在标签位置计算中使用 maxHeight。例如,在我的习惯中ButtonNode (a SKShapeNode其中包含一个SKLabelNode)我执行以下操作(简化):

// in the constructor of my custom 
// button node ...
let height = 30

self.label = SKLabelNode(text: "Back")
// in order to position properly, set 
// vertical alignment to baseline
self.label.verticalAlignmentMode = .baseline

let font = try Font(name: self.label.fontName!, size: self.label.fontSize)
// depending on the font you might want to add 
// an additional y offset to place labels 
// higher or lower within the node
let yOffset = (height - font.maxHeight) / 2)
let labelWidth = self.label.calculateAccumulatedFrame().width

let labelFrame = CGRect(
    x: 0,
    y: 0,
    width: labelWidth,
    height: height
)

self.path = CGPath(roundedRect: labelFrame, cornerWidth: 5, cornerHeight: 5, transform: nil)

self.label.position = CGPoint(x: labelFrame.width / 2, y: yOffset)

P.S.:如果您不想创建单独的Font类,并且您仍然希望代码在 iOS 和 macOS 上正常工作,您可以为NSFont and UIFont。由于您可以使用相同的构造函数,因此您只需要添加一个扩展来计算字体的最大高度(ascender + abs(descender)).

我更喜欢创建一个类,这样如果无法正确创建字体,我可以抛出错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpriteKit:有没有办法根据其基线将 SKLabelNode 居中 的相关文章

  • 设置/覆盖 UICollectionView 中单元格之间的填充

    我有一个 UICollectionView 但在获取单元格之间的填充时遇到了问题 理论上 我应该能够将屏幕除以 4 并且我可以获得包含 4 个图像的单元格大小 完美地占据屏幕宽度 但是 它选择不这样做 相反 它会创建 3 个具有巨大填充的图
  • iOS 上的 UIBezierPath 操作

    我从一条直线开始 我希望用户能够触摸并拖动该线 使其弯曲 实际上 他们有能力将线条操纵成波浪形状 我不确定从技术上实现这一目标的最简单方法 我首先创建了三次曲线的 UIBezierPaths 数组 目的是操纵控制点 但似乎一旦绘制了 UIB
  • iOS - 当 UIView 移动时将 UITextField 移动到不同的位置

    我有一个主 UIView 它通过开关向上移动 我有这个工作 那里没有问题 现在 UIView 当向下时 占据屏幕的大约一半 当它向上推时 它会显示底部 40px 在 UIView 中 当它处于向下状态时 它有一个 UITextField 并
  • 在 iOS 上使用 Web 服务的最佳方式?

    我想构建一个 iOS 应用程序 让您登录到网络服务 之后 应用程序将 当用户选择时 通过 https 发送登录名 密码以及请求的变量 例如 在请求 新闻更新 后 它将收到 XML 格式的请求信息 类似于
  • 如何使用完成处理程序等待 firestore 请求的完成

    我正在慢慢地了解完成处理程序 如果我有一个 firestore 查询 如果我想使用完成处理程序 则有点向后工作 当 firestore 查询完成时 我必须使用completion 但它的设置功能仍然让我感到困惑 因此 如果这是一个将闭包作为
  • 从 iOS 应用程序内的 Junos Pulse 获取用户凭据

    我正在通过 Junos Pulse 在 iPad 中建立 VPN 连接 以进入我组织的 Intranet 谁能告诉我是否有任何 iOS api 或 SDK 可用于获取在 iOS 应用程序内的 Junos pulse 中输入的用户凭据 Jun
  • UIDocumentInteractionController 阻止“打开方式”表中的空投

    在我的应用程序中 我允许用户通过 Instagram 分享照片 这需要使用 UIDocumentInteractionController 如果手机支持 则会自动检测空投 如何将其从 打开方式 操作表中删除 即使我使用 UIActivity
  • 在iOS上,“添加到主页”缓存保存在哪里,如何清除它?

    我正在 iPad iOS v7 上制作一个 html5 游戏 当我将其添加到主页时 它非常顽固地释放缓存 如果我在 Safari 中查看它 这会按照您所期望的方式工作 如果我刷新一次或两次 页面就会以最新状态缓存 但在主页上却是另一回事 它
  • iOS 中的构建对象文件扩展名是什么?

    当我在项目中构建java对象类时 将创建带有 class扩展名的构建文件 并且人类不可读 快速构建文件怎么样 example car java gt build gt car class 构建后会是什么 car swift gt build
  • 错误:更改核心数据模型后架构armv7的重复符号

    我有一个使用核心数据框架的应用程序 我工作得很好 我刚刚更改了数据模型 向一个实体添加一个属性 当我尝试构建它时 出现错误 duplicate symbol OBJC METACLASS AccountFolder in Users XXX
  • iphone NSDate 转换问题

    在我的 facebook 图表 Api 中 我正在获取这些数据 来自杰森 updated time 2011 05 17T14 52 16 0000 我正在使用此代码将其转换为有效的日期格式 NSDateFormatter df NSDat
  • 个人帐户开发者之间的 Apple 开发/分发证书

    我一直在到处寻找有关处理证书的正确答案 想象一下以下帐户 Joe拥有个人 Apple 帐户 但他根本不会编码 他只是发布了该应用程序并将其称为自己的 Bob还有一个个人 Apple 帐户 Bob 是一位编码专家 Joe 付费让他开发他的第一
  • 架构armv7的重复符号

    尝试在我现有的应用程序中使用 Layar SDK 时出现以下错误 我该如何解决这个问题 Ld Users pnawale Library Developer Xcode DerivedData hub afxxzaqisdfliwbzxbi
  • 指定访问组时出现 KeychainItemWrapper 错误

    相当长一段时间以来 我一直在使用 KeychainItemWrapper 的 ARC 版本成功读取和写入私有钥匙串项目 我现在正在努力将我的 iOS 应用程序转换为使用共享访问组 以便我的 2 个共享相同应用程序前缀的应用程序可以访问钥匙串
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • 为什么我的视图仍然以横向呈现?

    我的视图是由导航控制器控制的 因此我将导航控制器支持的方向设置为明确的纵向和纵向UpSideDown 这可以工作 但是如果调用视图时前一个视图处于横向状态 它将以横向方式呈现并保持横向状态 直到设备旋转 如何防止这种情况发生 这是我的代码
  • 避免 UIImage 的 imageNamed - 内存管理

    我正在经历这个链接 http akosma com 2009 01 28 10 iphone memory management tips 我遇到了一个点避免 UIImage 的 imageNamed 出于什么原因我们应该避免这种情况 它会
  • UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例

    In the UIWebView 如果包含文本的输入元素具有焦点 并且按下按钮导致输入失去焦点 则随后双击输入以重新获得焦点并从出现的弹出栏中选择 剪切 或 复制 或 粘贴 会导致这UIWebView因错误而崩溃 UIWebView cut
  • Swift C 回调 - Swift 类指针的 takeUnretainedValue 或 takeRetainedValue

    我有一些UIView or UITableViewCell 里面我有 C 回调 例如 CCallback bridge self observer data gt Void in let mySelf Unmanaged
  • 在故事板中的视图控制器之间滑动手势

    我希望添加左右滑动手势来在视图控制器之间进行更改 这是否可能 并且有没有一种简单的方法可以在故事板中执行此操作 谢谢 故事板允许您在两个视图控制器之间设置 Segues 我想说首先在视图之间附加 Segues 给它一个标识符 然后使用类似的

随机推荐