iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🍇

Improving Multi-line Text Display in SwiftUI with Optimized Line Breaks

に公開

Summary

  • Fewer line breaks in the middle of words, making it much easier to read!
  • Available on iOS 13.0+, macOS 10.15+, tvOS 13.0+, and watchOS 6.0+!

Google's BudouX: Tidying up Line Breaks in Japanese Text

Text is sometimes automatically broken based on the width of the screen or window. In Japanese, where there are no spaces between words or phrases, the line break positions can end up looking awkward.

https://twitter.com/hima_papa0831/status/1474679838942568450?s=20

google/budoux is a library for Python and JavaScript that solves this problem nicely.

https://github.com/google/budoux

Additionally, griffin-stewie/BudouX.swift makes this available in Swift.

https://github.com/griffin-stewie/BudouX.swift

And now, griffin-stewie/BudouX.swift v0.4.0 has been released, making it easy to use in SwiftUI as well.

https://github.com/griffin-stewie/BudouX.swift/releases/tag/v0.4.0

Just Replace Text with BudouXText

It can be used on iOS 13.0+, macOS 10.15+, tvOS 13.0+, and watchOS 6.0+ (essentially any environment where SwiftUI's Text is supported).

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。")
            .multilineTextAlignment(.center)
    }
}

Try replacing the SwiftUI Text part with BudouXText as shown above.

import SwiftUI
import BudouX

struct ContentView: View {
    var body: some View {
        BudouXText("あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。")
            .multilineTextAlignment(.center)
    }
}

Here is a preview showing both SwiftUI's Text and BudouXText side-by-side.

Since .multilineTextAlignment(.center) is specified, the power of BudouX is even more apparent! It's very easy to read.

BudouXText Implementation

The implementation of BudouXText can be found in Sources/BudouX/SwiftUI/BudouXText.swift.

// griffin-stewie/BudouX.swift v0.5.0

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public func BudouXText(_ key: String, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil, parser: BudouX.Parser = .init(), threshold: Int = BudouX.Parser.defaultThreshold, condition: (_ naturalLanguagesSupportedByParser: Set<String>) -> Bool = defaultBudouXTextCondition) -> SwiftUI.Text

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public func BudouXText(verbatim content: String, parser: BudouX.Parser = .init(), threshold: Int = BudouX.Parser.defaultThreshold, condition: (_ naturalLanguagesSupportedByParser: Set<String>) -> Bool = defaultBudouXTextCondition) -> SwiftUI.Text

Although it is not in lowerCamelCase, it is a global method that becomes available once you import BudouX, and it returns SwiftUI's Text.[1] It also supports localization.

The condition parameter, which is the last argument of the method, provides a Set of natural languages supported by the BudouX parser. For example, you can return true for Japanese text and false otherwise to apply BudouX conversion only to Japanese text.

All View Modifiers for SwiftUI's Text are Also Available

Due to the implementation described above, all View Modifiers available for SwiftUI's Text are fully available in BudouXText. Therefore, if there are any Japanese sentences where the line breaks are a concern, you can simply replace the Text with BudouXText.[2]

References

https://zenn.dev/griffin_stewie/articles/2112211657_introducing_budoux_swift

脚注
  1. There is an explanation in the Pull request as to why the naming is not lowerCamelCase even though it is a method. ↩︎

  2. One might think that a View Modifier for SwiftUI's Text, such as budouxed(_:), would have been better... However, there is an explanation in the Pull request as to why it did not end up that way. ↩︎

Discussion