watchOS 中带有 SwiftUI 的 NSAttributedString?

问题描述 投票:0回答:2

目标:使用 SwiftUI 在 watchOS 中描边文本

通过故事板项目,

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 的解决方案。

swift xcode swiftui nsattributedstring watchos
2个回答
0
投票

最简单的方法是绘制图像:

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

-2
投票

在最新的 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

© www.soinside.com 2019 - 2024. All rights reserved.