簡體   English   中英

如何使用顯式 NSLayoutManager、NSTextStorage、NSTextContainer 以編程方式設置 NSTextView?

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

按照蘋果文檔,我試圖通過它的兩個構造函數方法設置一個簡單的NSTextView

我將下面的代碼放在內容視圖的視圖控制器的viewDidAppear方法中。 textView 是NSTextView一個實例, frameRect 是內容視圖的框架。

以下 Swift 代碼有效(為我提供了一個可編輯的 textView,文本顯示在屏幕上):

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

以下不起作用(文本視圖不可編輯且屏幕上不顯示文本):

    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"))

我在第二個例子中做錯了什么? 我正在嘗試遵循 Apple 的“Cocoa Text Architecture Guide”中給出的示例,他們討論了通過顯式實例化其輔助對象網絡來設置NSTextView

您需要保留對您創建的NSTextStorage變量的引用。 我不太確定這一切的機制,但看起來文本視圖只保留對其文本存儲對象的弱引用。 一旦這個對象超出范圍,它就不再可用於文本視圖。 我想這符合 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"))
    }
}

在 Xcode 12.4 下測試。 在游樂場:

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