Search code examples
iosswiftmacostextviewuitextview

Instantly format a UITextView using AttributedString


I'm developing a macOS rich-text editor that applies pre-defined style for each line of the text view.

To format the lines, I'm using NSAttributedString, then, I'm inserting that string into my UITextView. To make things easier, I'm using a tool called SwiftRichString.

My code looks like below. It's straight-forward and works fine.

import Cocoa
import SwiftRichString
import AppKit

class ViewController: NSViewController {
    @IBOutlet var textView: NSTextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Format the string
        let style = Style {
            $0.font = NSFont(name: "Arial", size: 20)
            $0.color = NSColor.black
            $0.alignment = .center
        }
        let attributedText = "Hello World!".set(style: style)

        // Add formatted string to the text view
        textView.textStorage?.append(attributedText)
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

}

Current situation:

User is typing a formatted line. Then when user hits Return and types something, format of the new line returns back to the default style of the UITextView.

What I want:

User is typing a certain formatted line, then he hits Return. The next line should be formatted to another pre-defined style on-the-go.

Example:

  1. User is typing the Title line. Current style is (Arial, bold, 20pt).
  2. He hits Return.
  3. Next line should be styled as Normal Text using a pre-defined style (Arial, 12pt).

Important Note:

In my above code, I was able to format the line easily because it's hard-coded. My real issue is, how can I instantly format the next line, because the next line will be entered by the user. The style should be applied to the next line before user begins writing it.


Solution

  • Okay, I just figured out how to use typingAttributtes to solve this question (thanks to @Larme for the hint).

       // Define next attributes
       let attributes: [NSAttributedString.Key: Any] = [
           .foregroundColor: NSColor.red,
           .font: NSFont(name: "Arial", size: 12)!,
       ]
       
       // Assign attributes to the text view typing attributes
       textView.typingAttributes = attributes
    

    Very easy!