如何禁用 NSTextView 的自动换行?

发布于 2024-09-08 07:12:48 字数 68 浏览 2 评论 0原文

NSTextView 默认进行自动换行。我怎样才能禁用这个功能? 我正在制作一个 JSON 代码查看器,所以我必须禁用它。

NSTextView does word-wrap by default. How can I disable this?
I'm making a JSON code viewer, so I have to disable this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

得不到的就毁灭 2024-09-15 07:12:48

首先,本文档解释了原因和方式 - https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/TrackingSize.html#//apple_ref/doc/uid/20000927- CJBBIAAF

我从以下位置得到了解决方案: http:// lists.apple.com/archives/cocoa-dev/2008/May/msg02396.html

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

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

alt text

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

alt text

更新

我发现我的旧示例代码不足以使其完全正常工作。 (因为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 正在提供官方指南< /a> 正确创建 NSTextView 。我希望这有帮助。

更新 3

我在 Github 上发布了一个 示例项目。具体实现请参见此页面: https:// /github.com/Eonil/CocoaProgrammaticHowtoCollection/blob/master/ComponentUsages/TextView/ExampleApplicationController.swift?ts=4

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

if wordWrap {
    /// Matching width is also important here.
    let sz = scrollView.contentSize
    textView.frame = CGRect(x: 0, y: 0, width: sz.width, height: 0)
    textView.textContainer?.containerSize = CGSize(width: sz.width, height: CGFloat.greatestFiniteMagnitude)
    textView.textContainer?.widthTracksTextView = true
}
else {
    textView.textContainer?.widthTracksTextView = false
    textView.textContainer?.containerSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
}

First, this document explains why and how -- https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/TrackingSize.html#//apple_ref/doc/uid/20000927-CJBBIAAF

I got solution from: http://lists.apple.com/archives/cocoa-dev/2008/May/msg02396.html

You have to set NSTextView's maximum width to very large number to make this work correctly. (Just copy maximum height)
And enable horizontal scrolling of NSScrollView which is superview of the NSTextView.
See these pictures:

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

alt text

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

alt text

Update

I discovered my old sample code was insufficient to make it fully work correctly. (because of SDK version?)
Also
Here's my full source code snippet which disables word-wrap in 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)];  

Update 2

Now Apple is providing an official guide to create NSTextView correctly. I hope this helps.

Update 3

I posted an example project on Github. See this page for specific implementation: https://github.com/Eonil/CocoaProgrammaticHowtoCollection/blob/master/ComponentUsages/TextView/ExampleApplicationController.swift?ts=4

Here's a code snippet from the sample project.

if wordWrap {
    /// Matching width is also important here.
    let sz = scrollView.contentSize
    textView.frame = CGRect(x: 0, y: 0, width: sz.width, height: 0)
    textView.textContainer?.containerSize = CGSize(width: sz.width, height: CGFloat.greatestFiniteMagnitude)
    textView.textContainer?.widthTracksTextView = true
}
else {
    textView.textContainer?.widthTracksTextView = false
    textView.textContainer?.containerSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
}

洒一地阳光 2024-09-15 07:12:48

仅 Eonil 接受的答案中给出的三行对我来说不起作用,生成的文本视图不会水平滚动,因此无法看到长行的剪裁部分。

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

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

The three lines given in the accepted answer by Eonil alone did not work for me, the resulting text view did not scroll horizontally and therefore there was no way to see the clipped part of the long lines.

The full code snippet from the referenced cocoa-dev thread did produce the correct results. Specifically, this set of steps:

NSSize layoutSize = [textView maxSize];
layoutSize.width = layoutSize.height;
[textView setMaxSize:layoutSize];
[[textView textContainer] setWidthTracksTextView:NO];
[[textView textContainer] setContainerSize:layoutSize];
可爱暴击 2024-09-15 07:12:48

我在 NSTextView 上编写了一个扩展。

extension NSTextView {
    var wrapsLines: Bool {
        get {
            return self.textContainer?.widthTracksTextView ?? false
        }
        set {
            guard
                newValue != self.wrapsLines,
                let scrollView = enclosingScrollView,
                let textContainer = self.textContainer
                else { return }

            scrollView.hasHorizontalScroller = !newValue
            isHorizontallyResizable = !newValue
            textContainer.widthTracksTextView = newValue

            if newValue {
                self.frame.size[keyPath: \NSSize.width] = scrollView.contentSize.width
                maxSize = NSSize(width: scrollView.contentSize.width, height: CGFloat.greatestFiniteMagnitude)
                textContainer.size.width = scrollView.contentSize.width
            } else {
                let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
                maxSize = infiniteSize
                textContainer.size = infiniteSize
            }
        }
    }
}

I have written an extension on NSTextView.

extension NSTextView {
    var wrapsLines: Bool {
        get {
            return self.textContainer?.widthTracksTextView ?? false
        }
        set {
            guard
                newValue != self.wrapsLines,
                let scrollView = enclosingScrollView,
                let textContainer = self.textContainer
                else { return }

            scrollView.hasHorizontalScroller = !newValue
            isHorizontallyResizable = !newValue
            textContainer.widthTracksTextView = newValue

            if newValue {
                self.frame.size[keyPath: \NSSize.width] = scrollView.contentSize.width
                maxSize = NSSize(width: scrollView.contentSize.width, height: CGFloat.greatestFiniteMagnitude)
                textContainer.size.width = scrollView.contentSize.width
            } else {
                let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
                maxSize = infiniteSize
                textContainer.size = infiniteSize
            }
        }
    }
}
七秒鱼° 2024-09-15 07:12:48

我发现这个解决方案确实防止了换行,但对 NSTextView 产生了一些不幸的绘图后果。问题是,当包含文本视图的 NSPanel 被拖动到比文本行更宽时,NSView 的边界矩形(由底层布局管理器)调整为仅比文本稍长 - 显示 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 中正确绘制。

希望这对某人有帮助 - 如果没有我在这个网站上找到的所有好的修复,我不知道我会在哪里!

I found this solution did prevent line wrapping, but had some unfortunate drawing consequences for the NSTextView. The problem was that when the NSPanel containing the text views was dragged to be wider than the lines of text, the NSView's bounds rect was adjusted (by the underlying layout manager) to just be slightly longer than the text - revealing the NSPanel's background. Not what I had in mind ...

My solutions was to enable resizing in the NSPanel, constrain it to the horizontal by setting of min and max sizes and turn off horizontal resizing for the text view itself:

// 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];

This results in a monitor panel that can be horizontally resized, does not wrap lines, and draws properly in it's enclosing NSPanel.

Hope this helps someone - don't know where I'd be without all the good fixes I've found on this site!

鸢与 2024-09-15 07:12:48

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

Easiest way is in Interface Builder, in the inspector just change the drop-down menu.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文