如何禁用NSTextView的自动换行?

问题描述 投票:16回答:5

NSTextView默认情况下会自动换行。如何禁用此功能?我正在制作JSON代码查看器,因此必须禁用此功能。

cocoa word-wrap nstextview
5个回答
25
投票

我从http://lists.apple.com/archives/cocoa-dev/2008/May/msg02396.html获得了解决方案

您必须将NSTextView的最大宽度设置为非常大的数字才能正常工作。 (仅复制最大高度)并启用NSScrollView的水平滚动,它是NSTextView的超级视图。看到这些图片:

http://www.flickr.com/photos/47601728@N06/4759470529/

“>

http://www.flickr.com/photos/47601728@N06/4759470533/

更新

我发现我的旧示例代码不足以使其完全正常工作。 (因为SDK版本?)也这是我的完整源代码片段,该片段在OSX 10.8 SDK中禁用自动换行。

[self setMaxSize:CGSizeMake(FLT_MAX, FLT_MAX)];    
[self setHorizontallyResizable:YES];               
[[self textContainer] setWidthTracksTextView:NO];  
[[self textContainer] setContainerSize:CGSizeMake(FLT_MAX, FLT_MAX)];  

更新2

现在Apple is providing an official guide可正确创建NSTextView。我希望这会有所帮助。

更新3

我发布了example project on Github。具体实现请参见本页:https://github.com/Eonil/CocoaProgrammaticHowtoCollection/blob/master/ComponentUsages/TextView/ExampleApplicationController.swift?ts=4

这是示例项目中的代码段。

        if wordwrap {
            /// Matching width is also important here.
            let sz1                                     =   scroll1.contentSize
            text1.frame                                 =   CGRect(x: 0, y: 0, width: sz1.width, height: 0)
            text1.textContainer!.containerSize          =   CGSize(width: sz1.width, height: CGFloat.max)
            text1.textContainer!.widthTracksTextView    =   true
        } else {
            text1.textContainer!.widthTracksTextView    =   false
            text1.textContainer!.containerSize          =   CGSize(width: CGFloat.max, height: CGFloat.max)
        }

[Eonil独自接受的答案中给出的三行代码对我不起作用,结果文本视图没有水平滚动,因此无法查看长行的剪切部分。

引用的cocoa-dev线程的完整代码段确实产生了正确的结果。具体来说,这套步骤:

NSSize layoutSize = [textView maxSize];
layoutSize.width = layoutSize.height;
[textView setMaxSize:layoutSize];
[[textView textContainer] setWidthTracksTextView:NO];
[[textView textContainer] setContainerSize:layoutSize];

我发现此解决方案确实可以防止换行,但是不幸的是,NSTextView产生了一些绘图效果。问题是,当将包含文本视图的NSPanel拖动到比文本行宽时,NSView的边界rect(由底层布局管理器)调整为略长于文本,从而显示了NSPanel的背景。不是我的想法...

我的解决方案是在NSPanel中启用调整大小,通过设置最小和最大大小将其限制为水平,并为文本视图本身关闭水平调整大小:

// some fragments from the creation of the NSPanel
// resizable NSPanel created
mMonitorPanel = [[NSPanel alloc] initWithContentRect: monitorRect
              styleMask: (NSTitledWindowMask| NSMiniaturizableWindowMask | NSResizableWindowMask)
                backing: NSBackingStoreBuffered defer: NO];

 // constrain resizing to horizontal only, with obvious limits ...
[mMonitorPanel setContentMaxSize: NSMakeSize(1000, 600)];
[mMonitorPanel setContentMinSize: NSMakeSize(300,  600)];

// a fragment from the init that creates an instance of a subclass of NSTextView ...

[self setVerticallyResizable: NO];
[self setHorizontallyResizable: NO];  // rather than YES as prior code snippet

// the rest is the same as above
[[self textContainer] setContainerSize: NSMakeSize(FLT_MAX, FLT_MAX)];
[[self textContainer] setWidthTracksTextView: NO];

这将导致监视器面板可以水平调整大小,不换行,并且可以在其封闭的NSPanel中正确绘制。

希望这对某人有帮助-如果没有在此站点上找到的所有好的修补程序,不知道我会在哪里!

我在NSTextView上写了扩展名。

extension NSTextView {
    func wrapText(_ isWrapped: Bool) {
        guard let scrollView = enclosingScrollView else { return }
        scrollView.hasHorizontalScroller = !isWrapped
        isHorizontallyResizable = !isWrapped
        let width = isWrapped ? Int(scrollView.contentSize.width) : Int.max
        maxSize = NSSize(width: width, height: Int.max)
        textContainer?.size = NSSize(width: width, height: Int.max)
        textContainer?.widthTracksTextView = isWrapped
    }
}

此代码已经解耦了,只想附上一个NSScrollView

最简单的方法是在Interface Builder中,在检查器中只需更改下拉菜单。


6
投票

[Eonil独自接受的答案中给出的三行代码对我不起作用,结果文本视图没有水平滚动,因此无法查看长行的剪切部分。


0
投票

我发现此解决方案确实可以防止换行,但是不幸的是,NSTextView产生了一些绘图效果。问题是,当将包含文本视图的NSPanel拖动到比文本行宽时,NSView的边界rect(由底层布局管理器)调整为略长于文本,从而显示了NSPanel的背景。不是我的想法...


0
投票

我在NSTextView上写了扩展名。


-7
投票

最简单的方法是在Interface Builder中,在检查器中只需更改下拉菜单。

© www.soinside.com 2019 - 2024. All rights reserved.