缩放 NSTextView 并在 Swift 中保留自动换行 2

Zoom a NSTextView and preserve word wrap in Swift 2

有没有办法缩放 NSTextView(富文本)的内容保持字体大小不变保留自动换行window?

为什么我需要这样做:

用户应该能够编写可以放大的富文本,而不会影响文档本身的内容,同时仍保持与 window 相同的大小。如果用户难以阅读文本,这将使调整整体缩放级别变得容易。

如有任何帮助,我们将不胜感激!

我能够弄明白——自从我最初提出这个问题以来学到了很多东西。必须考虑坐标转换、错误和许多其他事项:

//
//  ZoomingTextView.swift
//
// 
// Joseph E.
//
// Use/modify to your convenience

import Cocoa

class ZoomingTextView : NSTextView {

    /// 100% 1x1 unit scaling:
    let unitSize: NSSize = NSSize(width: 1.0, height: 1.0)

    /// The last scaling factor that this textview experienced
    private(set) var oldScaleFactor: Double = 1.0

    /// The current zoom factor
    private(set) var zoomFactor: Double = 1.0

    /// Zooms to the specified scaling factor.
    /// - Parameter factor: The scaling factor. 1.0 = 100%
    func zoomTo(factor: Double) {
        var scaleFactor = factor

        // No negative values:
        if scaleFactor < 0 {
            scaleFactor = abs(scaleFactor)
        }

        // No 0 value allowed!
        if scaleFactor == 0.0 {
            scaleFactor = 1.0
        }

        // Don't repeatedly zoom in on 100%
        // Prevents glitches
        if (scaleFactor < 1.01 && scaleFactor > 0.99) {
            // we'll only reach here if scale factor is about 1.0
            if (oldScaleFactor < 1.01 && oldScaleFactor > 0.99) {
                // print("old and new scale factor are 1.0")
                // For some reason, if we try to set the zoom to 100% when the zoom is
                // already 100%, everything disappears. This prevents that from
                // happening.
                return
            }
        }

        // Don't do redundant scaling:
        if scaleFactor == oldScaleFactor {
            // We've already scaled.
            return
        }


        // Reset the zoom before re-zooming
        scaleUnitSquareToSize(convertSize(unitSize, fromView: nil))

        // Perform the zoom on the text view:
        scaleUnitSquareToSize(NSSize(width: scaleFactor, height: scaleFactor))


        // Handle the details:
        let tc = textContainer!
        let lm = layoutManager!

        // To make word-wrapping update:
        let scrollContentSize = enclosingScrollView!.contentSize

        // Necessary for word wrap
        frame = CGRect(x:0, y:0, width: scrollContentSize.width, height: 0.0)

        tc.containerSize = NSMakeSize(scrollContentSize.width, CGFloat.max)
        tc.widthTracksTextView = true
        lm.ensureLayoutForTextContainer(tc)

        // Scroll to the cursor! Makes zooming super nice :)
        alternativeScrollToCursor()

        needsDisplay = true

        zoomFactor = scaleFactor

        // Keep track of the old scale factor:
        oldScaleFactor = scaleFactor
    }

    /// Forces the textview to scroll to the current cursor/caret position.
    func alternativeScrollToCursor() {
        if let cursorPosition: NSInteger = selectedRanges.first?.rangeValue.location {
            scrollRangeToVisible(NSRange(location: cursorPosition, length: 0))
        }
    }
}