Skip to content

Instantly share code, notes, and snippets.

@niw
Last active November 29, 2023 05:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niw/f0eeea40468ab8c980f5b122d3a57ffd to your computer and use it in GitHub Desktop.
Save niw/f0eeea40468ab8c980f5b122d3a57ffd to your computer and use it in GitHub Desktop.
Texting line height on NSTextView with TextKit 2
import AppKit
import Foundation
final class MainView: NSView {
private let textView: NSTextView
override init(frame frameRect: NSRect) {
textView = NSTextView(usingTextLayoutManager: true)
super.init(frame: frameRect)
var constraints = [NSLayoutConstraint]()
defer {
NSLayoutConstraint.activate(constraints)
}
if let textStorage = textView.textStorage {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = 20.0
paragraphStyle.maximumLineHeight = 20.0
let text = NSAttributedString(
string: """
Lorem Ipsum is simply dummy text of the
吾輩は猫である。名前はまだ無い。
printing and typesetting industry.
どこで生れたかとんと見当がつかぬ。
Lorem Ipsum has been the industry'
""",
attributes: [
.font: NSFont(name: "Helvetica", size: 20.0)!,
.foregroundColor: NSColor.textColor,
.paragraphStyle: paragraphStyle
])
textStorage.append(text)
}
if let layoutManager = textView.textLayoutManager {
//layoutManager.usesFontLeading = false
layoutManager.delegate = self
}
addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
constraints.append(contentsOf: [
textView.topAnchor.constraint(equalTo: topAnchor, constant: 10.0),
textView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10.0),
textView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10.0),
textView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10.0)
])
}
required init?(coder: NSCoder) {
fatalError()
}
}
extension MainView: NSTextLayoutManagerDelegate {
}
final class AppDelegate: NSObject {
private let window: NSWindow
override init() {
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 400.0, height: 400.0),
styleMask: [.titled, .closable, .resizable],
backing: .buffered,
defer: false
)
window.contentView = MainView()
super.init()
}
}
extension AppDelegate: NSApplicationDelegate {
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
true
}
func applicationWillFinishLaunching(_ notification: Notification) {
window.makeKeyAndOrderFront(self)
window.center()
}
}
autoreleasepool {
var psn = ProcessSerialNumber(highLongOfPSN: 0, lowLongOfPSN: UInt32(kCurrentProcess))
TransformProcessType(&psn, ProcessApplicationTransformState(kProcessTransformToForegroundApplication))
let app = NSApplication.shared
let delegate = AppDelegate()
app.delegate = delegate
app.run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment