通过在单词之间插入空格来对齐文本,而不是在 iOS UITextView 中的字符之间插入空格

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

我正在尝试证明

UITextView
中的某些文本是合理的。这很容易,只是对齐算法会在一个单词内的字符之间插入空格,而不是在单词之间插入空格。因此,段落中间的一行可能如下所示:

A example of some
j u s t i f i e d
text that is wit-
hin some kind  of  
text box in app.

但是我想禁止在单词中插入空格,所以:

A example of some
justified    text
that  is   within 
some kind of text 
box in app.

有关视觉表示,请参阅此问题,这基本上与我遇到的问题相同(除了我使用英语)。

这是我的代码:

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .justified
paragraphStyle.hyphenationFactor = 1

let textView = UITextView()
let attributes = [NSAttributedString.Key.paragraphStyle: paragraphStyle]
textView.attributedText = NSAttributedString(string: "some text", attributes: attributes)

从我所做的搜索量来看,看起来我可能需要使用

Core Text
自己来做这件事。我对 Apple 生态系统和 swift 都很陌生,所以我的问题是:是否有一种开箱即用的方式来完成我需要的事情?如果没有,我将不胜感激一些帮助,为我指明自己实现这一目标的正确方向。

编辑:这是我所看到的完整示例:

import SwiftUI
import UIKit

struct JustifiedTextView: UIViewRepresentable {
    let string = "An example of some justified text that is within some kind of text box in app containing some longwords and some other short words. DonMag might have some ideas on how to only apply spacing within words not characters."
    
    func makeUIView(context: Context) -> UITextView {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .justified
        paragraphStyle.hyphenationFactor = 1
        let attributes = [
            NSAttributedString.Key.paragraphStyle : paragraphStyle,
            NSAttributedString.Key.font : UIFont.systemFont(ofSize: 22)
        ]
        let textView = UITextView()
        textView.attributedText = NSAttributedString(string: string, attributes: attributes)
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = string
    }
}

我这样使用上面的:

import SwiftUI

struct MyView: View {
    var body: some View {
        HStack {
            JustifiedTextView()
            JustifiedTextView()
            JustifiedTextView()
        }
    }
}

这是上述在 iOS 模拟器(iPhone 15 Pro、iOS 17.2)上的结果:

ios swift uitextview justify textkit
1个回答
0
投票

您可以使用

NSTextLayoutManagerDelegate
shouldBreakLineBefore
可靠地控制线断成两半的位置。

https://developer.apple.com/documentation/uikit/nstextlayoutmanagerdelegate/3810021-textlayoutmanager

您需要检查早期文本布局片段的范围(使用

textLayoutManager.enumerateTextLayoutFragments(from:)
之类的内容或使用视觉坐标),并查看建议换行符的文本范围是否不包含空格。

控制自己的布局可能有点棘手,如果不小心,可能会陷入无限循环。更明智的方法可能是更改片段范围内文本的字距调整,以在需要时容纳更多内容。

NSTextLayoutManagerDelegate
方法也会为您提供帮助。

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