3

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!

yaosamo
  • 126
  • 1
  • 10
  • Welcome to Stack Overflow! Please take the [tour](https://stackoverflow.com/tour) and see: [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) and [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). Please make sure you include a buildable sample of what you have tried. – Yrb Dec 18 '21 at 16:24
  • tried https://stackoverflow.com/questions/1951272/giving-an-nstextview-some-padding-a-margin ? – battlmonstr Dec 18 '21 at 17:49
  • @battlmonstr It's interesting that they're trying with textContainerOrigin - I'm going to explore that as well, thank you! – yaosamo Dec 19 '21 at 05:45
  • Some progress: I've created a rich editor with Storyboard https://i.ibb.co/LNsXfrN/ezgif-com-gif-maker.gif and applied paragraph indent. In the source code this is how it looks like https://i.ibb.co/YPwdN18/Screen-Shot-2021-12-18-at-9-43-00-PM.png so I'm trying to apply this to my NSTextView now. – yaosamo Dec 19 '21 at 05:48
  • @battlmonstr origin is pretty cool solution unfortunately it doesn't allow you to click on lines. Looks like NSParagraphStyle is what I'm looking for. – yaosamo Dec 19 '21 at 06:21
  • Some update after research - the headIndent and firstLineHeadIndent in NSParagraphStyle can be deleted with backspace. But I need it to be hardcoded. So keep looking. – yaosamo Dec 21 '21 at 16:49

1 Answers1

3

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

yaosamo
  • 126
  • 1
  • 10