【问题标题】:Zoom a NSTextView and preserve word wrap in Swift 2在 Swift 2 中缩放 NSTextView 并保留自动换行
【发布时间】:2016-03-26 19:32:29
【问题描述】:

有没有办法缩放 NSTextView(富文本)的内容保持字体大小相同,这也将自动换行保留到窗口的尺寸 ?

为什么我需要这样做:

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

任何帮助将不胜感激!

【问题讨论】:

    标签: swift macos nstextview


    【解决方案1】:

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

    //
    //  ZoomingTextView.swift
    //
    // http://stackoverflow.com/questions/36239926/zoom-a-nstextview-and-preserve-word-wrap-in-swift-2
    // 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))
            }
        }
    }
    

    【讨论】:

    • 谢谢。两个问题:首先,frame 变量实际上没有被使用,这会产生一个警告。其次,文本实际上并不是一直都在换行;有时,布局会卡在某个宽度上。更改文本视图的宽度会再次导致布局。有一个修复:使用textContainerChangedGeometry() 而不是ensureLayoutForTextContainer()
    • 谢谢马丁。在我以此为生之前,它已经过时并且写得非常糟糕。我为之构建的原始项目将不再编译,因此很难挽救它。
    • 不用担心。我只是在寻找有关此问题的一些灵感,并以您的代码为起点。我认为添加此更正可能会很好,以使人们在将来发现此问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多