简体   繁体   English

如何使用显式 NSLayoutManager、NSTextStorage、NSTextContainer 以编程方式设置 NSTextView?

[英]How to set up an NSTextView programmatically with explicit NSLayoutManager, NSTextStorage, NSTextContainer?

Following the apple documentation I am trying to set up a simple NSTextView via its two constructor methods.按照苹果文档,我试图通过它的两个构造函数方法设置一个简单的NSTextView

I am placing the below code inside the viewDidAppear method of the view controller of the content view.我将下面的代码放在内容视图的视图控制器的viewDidAppear方法中。 textView is an instance of NSTextView , frameRect is the frame of the content view. textView 是NSTextView一个实例, frameRect 是内容视图的框架。

The following Swift code works (gives me an editable textView with the text showing on the screen):以下 Swift 代码有效(为我提供了一个可编辑的 textView,文本显示在屏幕上):

    textView = NSTextView(frame: frameRect!)
    self.view.addSubview(textView)
    textView.textStorage?.appendAttributedString(NSAttributedString(string: "Hello"))

The following does NOT work (text view is not editable and no text shown on the screen):以下不起作用(文本视图不可编辑且屏幕上不显示文本):

    var textStorage = NSTextStorage()
    var layoutManager = NSLayoutManager()
    textStorage.addLayoutManager(layoutManager)
    var textContainer = NSTextContainer(containerSize: frameRect!.size)
    layoutManager.addTextContainer(textContainer)
    textView = NSTextView(frame: frameRect!, textContainer: textContainer)

    textView.editable = true
    textView.selectable = true
    self.view.addSubview(textView)

    textView.textStorage?.appendAttributedString(NSAttributedString(string: "Hello more complex"))

What am I doing wrong in the second example ?我在第二个例子中做错了什么? I am trying to follow the example given in Apple's "Cocoa Text Architecture Guide" where they discuss setting up an NSTextView by explicitly instantiating its web of helper objects.我正在尝试遵循 Apple 的“Cocoa Text Architecture Guide”中给出的示例,他们讨论了通过显式实例化其辅助对象网络来设置NSTextView

You need to keep a reference to the NSTextStorage variable you create.您需要保留对您创建的NSTextStorage变量的引用。 I'm not quite sure about the mechanics of it all, but it looks like the text view only keeps a weak reference to its text storage object.我不太确定这一切的机制,但看起来文本视图只保留对其文本存储对象的弱引用。 Once this object goes out of scope, it's no longer available to the text view.一旦这个对象超出范围,它就不再可用于文本视图。 I guess this is in keeping with the MVC design pattern, where views (the NSTextView in this case) are meant to be independent of their models (the NSTextStorage object).我想这符合 MVC 设计模式,其中视图(在这种情况下为NSTextView )意味着独立于它们的模型( NSTextStorage对象)。

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    var textView: NSTextView!
    var textStorage: NSTextStorage! // STORE A REFERENCE

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        var view = window.contentView as NSView
        textStorage = NSTextStorage()
        var layoutManager = NSLayoutManager()
        textStorage.addLayoutManager(layoutManager)
        var textContainer = NSTextContainer(containerSize: view.bounds.size)
        layoutManager.addTextContainer(textContainer)
        textView = NSTextView(frame: view.bounds, textContainer: textContainer)

        textView.editable = true
        textView.selectable = true
        view.addSubview(textView)

        textView.textStorage?.appendAttributedString(NSAttributedString(string: "Hello more complex"))
    }
}

Tested under Xcode 12.4.在 Xcode 12.4 下测试。 in Playgrounds:在游乐场:

import Cocoa
import AppKit

let textViewFrame = CGRect(x: 0, y: 0, width: 250, height: 90)
let textStorage = NSTextStorage()
var layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
var textContainer = NSTextContainer(containerSize: textViewFrame.size)
layoutManager.addTextContainer(textContainer)
let textView = NSTextView(frame: textViewFrame, textContainer: textContainer)
textView.isEditable = true
textView.isSelectable = true
textView.textColor = NSColor.red
textView.string = "Why is this so complicated..."
#import <Cocoa/Cocoa.h>

@interface TextViewController : NSObject {

    NSLayoutManager *secondLayout;

    IBOutlet NSSplitView *columnView;
    IBOutlet NSTextView *bottomView;

}

- (IBAction) addColumn: (id)sender;

@end
#import "TextViewController.h"

@implementation TextViewController

- (void)awakeFromNib
{
    NSTextStorage *storage = [bottomView textStorage];
    secondLayout = [NSLayoutManager new];
    [storage addLayoutManager: secondLayout];
    [secondLayout release];
    [self addColumn: nil];
    [self addColumn: nil];
}


- (IBAction) addColumn: (id)sender
{
    NSRect frame = [columnView frame];

    NSTextContainer *container = [[NSTextContainer alloc]
                                  initWithContainerSize: frame.size];
    [container setHeightTracksTextView: YES];
    [container setWidthTracksTextView: YES];

    [secondLayout addTextContainer: container];
    [container release];
    NSTextView *newView = [[NSTextView alloc] initWithFrame: frame
                                              textContainer: container];
    [columnView addSubview: newView];
    [newView release];
}

@end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM