Justify text by inserting spaces between words, not between characters in iOS UITextView

95 views Asked by At

I am trying to justify some text in a UITextView. That's easy enough, except the justification algorithm would insert spaces between characters within one word, rather than insert spaces between words. So, one line in the middle of the paragraph could look like this:

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.

But I would like to prohibit spaces from being inserted within words, so:

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

For a visual representation, see this question which is basically the same problem I'm having (except I'm using English).

This is my code:

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)

From the amount of searching that I have done, it looks like I may need to use Core Text to do this myself. I am very new to the Apple ecosystem and to swift, so my question is: is there an out-of-the-box way of doing what I need? If not, I would appreciate some help to point me in the right direction to implement this myself.

EDIT: here is a full example for what I'm seeing:

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

And I use the above like this:

import SwiftUI

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

Here is the result of the above on the iOS Simulatior (iPhone 15 Pro, iOS 17.2):

enter image description here

0

There are 0 answers