WKInterfaceLabel 通过 setAttributedText 提供对 NSAttributedString 的支持,它提供了简单易用的描边文本支持。
但是,对于使用 SwiftUI 的新项目, WKInterfaceLabel 在不存在的故事板之外不可用:
不要自己创建此类的子类或实例。相反,在界面控制器类中定义插座并将它们连接到故事板文件中的相应对象。
open class WKInterfaceLabel : WKInterfaceObject {
open func setText(_ text: String?)
open func setTextColor(_ color: UIColor?)
open func setAttributedText(_ attributedText: NSAttributedString?)
}
'init()'不可用
那么,我们如何在 watchOS 中使用 NSAttributedString 和 SwiftUI 呢?
旁注:
未来,我希望新的 AttributedString 能够可靠地取代 NSAttributedString,但从 watchOS 8 和 iOS 15 开始,AttributedString 是破损且不完整。这迫使我寻找一种在 watchOS 中使用 NSAttributedString 和 SwiftUI 的解决方案。
最简单的方法是绘制图像:
func renderImage(_ attributedString: NSAttributedString, for width: CGFloat) -> UIImage? {
let boundingRect = attributedString.boundingRect(with: CGSize(width: width, height: .infinity), options: [.usesLineFragmentOrigin], context: nil)
UIGraphicsBeginImageContextWithOptions(boundingRect.size, false, 0)
attributedString.draw(in: CGRect(origin: .zero, size: boundingRect.size))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
然后将其与 Image() 一起使用
if let image = renderImage(longText, for: geometry.size.width) {
Image(uiImage: image)
}
在最新的 swiftUI 中,您可以使用
AttributedString
代替 NSAttributedString
。
详细说明如何使用它,您可以在苹果文档中找到:https://developer.apple.com/documentation/foundation/attributedstring
但是您仍然可以在 swiftUI 应用程序中使用 NSAttributedString 来包装原始 NSTextField(macos) / UITextField(IOS) 控件
macos 包装器示例(必须很容易重写):
import SwiftUI
import Cocoa
@available(OSX 11.0, *)
public struct AttributedText: NSViewRepresentable {
private let text: NSAttributedString
private let selectable: Bool
public init(attributedString: NSAttributedString, selectable: Bool = true) {
self.text = attributedString
self.selectable = selectable
}
public func makeNSView(context: Context) -> NSTextField {
let textField = NSTextField(labelWithAttributedString: text)
textField.preferredMaxLayoutWidth = textField.frame.width
textField.allowsEditingTextAttributes = true // Fix of clear of styles on click
textField.isSelectable = selectable
return textField
}
public func updateNSView(_ textField: NSTextField, context: Context) {
textField.attributedStringValue = text
}
}
但在大多数情况下,最好还是使用 SwiftUI 的原生方式——
AttributedString
。