使用NSDocument在第二个ViewController中保存

时间:2018-12-27 16:37:47

标签: swift xcode cocoa nsdocument

我正在尝试简单地使用NSDocument保存到rtf。该代码可以正常工作,但是当我尝试将其保存为不是窗口控制器的初始子级的视图控制器时,它会从模态中引发错误,提示“文档“”无法另存为””。

如何将文件保存到Second View Controller?

             Window Controller
                    |
           Login View Controller

          |                |
SidebarViewContoller   ViewController1
                                 |
                                  TableViewController 2 Replaces VC1  
                                   Save TextView in this VC

我希望能够从ViewController2中的textView将数据写入My NSDocument并将其保存到桌面 就像您在Pages中一样

这是代码

// Document.swift

class Document: NSDocument {

var text = NSAttributedString()
var documentViewController: DocumentViewController? {
    return windowControllers[0].contentViewController as? DocumentViewController
}


override init() {
    super.init()
    // Add your subclass-specific initialization here.
}

override class var autosavesInPlace: Bool {
    return true
}

override func makeWindowControllers() {
    // Returns the Storyboard that contains your Document window.
    let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
    let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
    self.addWindowController(windowController)
}

override func data(ofType typeName: String) throws -> Data {
    // Save the text view contents to disk
if let textView = documentViewController?.textView {
        let rangeLength = textView.string.count

    textView.breakUndoCoalescing()
    let textRange = NSRange(location: 0, length: rangeLength)
    if let contents = textView.rtf(from: textRange) {
            return contents
        }
    }
    throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
}

override func read(from data: Data, ofType typeName: String) throws {
    if let contents = NSAttributedString(rtf: data, documentAttributes: nil) {
        text = contents
    }
}

// SecondViewController

override func viewDidAppear() {
    let document = self.view.window?.windowController?.document as!   Document
    textView.textStorage?.setAttributedString(document.text)
}

1 个答案:

答案 0 :(得分:0)

在应用中进行设置的方式将无法将整个NSDocument的内容置于文本视图中。假设您在表格视图中有10个项目,选择一个项目会在文本视图中填充一些文本。您将无法为单个文档中的10个表视图项中的每一个都拥有一个NSDocument。

您要做的是创建一个表示文本文件的数据结构。想一想书中的一章或剧本中的场景。在您的NSDocument子类中,将具有这些数据结构的数组。保存文档时,将其另存为文件包装器,这是一个文件目录,看起来像Finder中的单个文件。在文件包装器中,表视图中的每个项目都会有一个文本文件。请参阅以下文章,以了解有关文件包装器的更多信息:

Working with File Wrappers in Swift

现在,您要了解的是在表格视图选择更改时如何填充文本视图。对于Mac故事板,这样做很痛苦,因为表格视图的控制器和文本视图的控制器是单独的场景。在表视图的视图控制器中实现委托方法tableViewSelectionDidChange。使用parent属性获取拆分视图控制器。使用拆分视图控制器获取文本视图的控制器。将选定的行传递到文本视图的控制器,并使用它来获取正确的文本文件以在文本视图中显示。

拆分视图控制器应存储对NSDocument的引用。使用parent属性可从文本视图的控制器访问拆分视图控制器。通过使用拆分视图控制器,您可以访问文档以用与表视图中所选项目相对应的文本文件内容填充文本视图。