Search code examples
objective-cmacosswiftuiuitextfieldswiftui-texteditor

Adding margins to TextEditor


I'm adding margins to the TextEditor. While keeping these margins as clickable area. I was able to add textContainerInset and problem is that added Inset is not clickable.

Current code:

extension NSTextView {
  open override var frame: CGRect {
    didSet {
        textContainerInset = CGSize(width: 72, height: 72)
      }
   }
}

Current Preview:

Intended behavior (Pages):

Would be grateful for an advice. Thank you very much!


Solution

  • so I found a simple solution and hard one.

    1. Simple one

        import SwiftUI
    
    
    extension NSTextView {
      open override var frame: CGRect {
        didSet {
            // Top inset
            textContainerInset = NSSize(width: 0, height: 72)
            // Left fragment padding <<< This is what I was looking for
            textContainer?.lineFragmentPadding = 72
            }
        }
    }
    
    
    struct TextEditingView: View {
        @State private var fullText: String = "One \nTwo \nThree"
    
    
        var body: some View {
            TextEditor(text: $fullText)
                .frame(width: 720, height: 480)
                .font(.system(size: 24, design: .monospaced))
                
    
            }
    
        }
    

    As result you get this: TextEditor with margins on left

    A repository of the demo: https://github.com/yaosamo/Swift-TextView-Demo

    2. Second solution

    Using NSParagraphStyle, headIndent, firstLineHeadIndent I believe this is how indents on Pages on Mac implemented. I do not know tho how they persist default indent. If you open ruler you will see that it set to 1 and you can't go below it.

    Using code of (AppKit) Tab insertion inside of NSTextBlock

    class ParagraphStyle {
    
    let bgColor: NSColor
    let paragraphStyle: NSParagraphStyle
    
    init(bgColor: NSColor) {
        self.bgColor = bgColor
        //Set paragraph style
        self.paragraphStyle = {
            let mutableParagraphStyle = NSMutableParagraphStyle()
            let specialBlock = CustomTextBlock(bgColor: bgColor)
            mutableParagraphStyle.textBlocks.append(specialBlock)
            mutableParagraphStyle.headIndent = 50 // Add indent here
            let style = mutableParagraphStyle as NSParagraphStyle
            return style
        }()
    }}
    

    you can add headIndent to text style. And it will work for copy that you insert there. Problem like I said if you start typing Indents break and I don't know how to preserve it.

    First one works for me exactly how I want it. Next will figure out how to use headIndent/FirstlineheadIndent

    Thanks to this community I was able to find a solution! Don't give up you also can make it! :D