具有多个NSTextContainers的NSLayoutManager导致UITextView不可选择/编辑

5

我正在尝试实现一种多页文本编辑布局,就像Pages、MS Word等软件中的布局。在OS X上,可以通过创建一个NSLayoutManager和一个NSTextStorage来为多个NSTextViews实现此功能。每个NSTextView都有自己的NSTextContainer。下面是OS X的示例代码。这里有一个简单的例子,可以让文本在两个NSTextViews之间传播:

import Cocoa

class ViewController: NSViewController {

let layoutManager = NSLayoutManager()
let textStorage = NSTextStorage(attributedString: NSAttributedString(string: "This is a test"))
let textContainer1 = NSTextContainer()
let textContainer2 = NSTextContainer()

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    textStorage.addLayoutManager(layoutManager)

    textContainer1.widthTracksTextView = true
    textContainer1.heightTracksTextView = true
    textContainer2.widthTracksTextView = true
    textContainer2.heightTracksTextView = true

    let textView1 = NSTextView(frame: CGRectMake(0, 100, 100, 100), textContainer: textContainer1)
    textView1.backgroundColor = NSColor.greenColor()
    self.view.addSubview(textView1)
    layoutManager.addTextContainer(textContainer1)


    let textView2 = NSTextView(frame: CGRectMake(200, 100, 100, 100), textContainer: textContainer2)
    textView2.backgroundColor = NSColor.greenColor()
    self.view.addSubview(textView2)
    layoutManager.addTextContainer(textContainer2)
}
}

这个可以正常工作。

然而,在尝试在iOS上使用UITextView时,UITextViews变得不可选择或编辑。以下是我的iOS代码:

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

let layoutManager = NSLayoutManager()
let textStorage = NSTextStorage(attributedString: NSAttributedString(string: "This is a test. This text should spread over two UITextViews. Bla bla bla bla bla bla bla bla bla bla bla bla bla"))
let textContainer1 = NSTextContainer()
let textContainer2 = NSTextContainer()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.        

    textStorage.addLayoutManager(layoutManager)

    textContainer1.heightTracksTextView = true
    textContainer1.widthTracksTextView = true
    textContainer2.heightTracksTextView = true
    textContainer2.widthTracksTextView = true

    let textView1 = UITextView(frame: CGRectMake(0, 100, 100, 100), textContainer: textContainer1)
    textView1.scrollEnabled = false
    textView1.delegate = self
    textView1.editable = true
    textView1.selectable = true
    textView1.backgroundColor = UIColor.greenColor()
    self.view.addSubview(textView1)
    layoutManager.addTextContainer(textContainer1)

    let textView2 = UITextView(frame: CGRectMake(200, 100, 100, 100), textContainer: textContainer2)
    textView2.scrollEnabled = false
    textView2.delegate = self
    textView2.editable = true
    textView2.selectable = true
    textView2.backgroundColor = UIColor.greenColor()
    self.view.addSubview(textView2)
    layoutManager.addTextContainer(textContainer2)

}
}

文本会从一个UITextView流到另一个,但是它不可编辑。如果您有任何建议,我将非常感激。

我在谷歌上搜索了这个问题,并发现其他人也遇到了同样的问题,但没有找到解决方法。


你找到解决方案了吗? - Yasser Farrag
我也想知道这个答案。 - Juraj Antas
2个回答

0

我也一直在寻找答案,似乎当UITextView与其他文本视图共享布局管理器时,文本视图就会变得静态。

这个问题在第375页中有详细说明:

因为您可以轻松地向布局管理器添加其他文本容器,并且UITextView使用布局管理器,所以您可能认为创建多列可编辑的UITextView很容易。不幸的是,情况并非如此。如果UITextView被分配了多个文本容器[sic],它将变得静态,无法响应用户交互,例如编辑或选择。这是一个已知的问题,目前“按设计”。


我观察到了略微不同的行为。我的场景是1个布局管理器连接到N个文本容器。我根据需要从这些0...N-1个文本容器中生成文本视图。我观察到第0个文本视图(第一个)具有selectable = true。我创建的所有其他文本视图都具有selectable = false,无论我是否从层次结构中删除了先前的文本视图。相当令人困惑的行为,可能是设计上的错误。 - Nirav Bhatt

0

我的解决方案是保留一个文本数组,由布局管理器为每个文本容器和UITextView呈现。

注意:这些UITextView不应该作为子视图添加到任何父视图中。

使用以下代码获取每个文本容器和文本视图的文本。

let range = layoutManager.glyphRange(for: textContainer)
        let textViewText = (text as NSString).substring(with: range)
        strings.append(textViewText)

在获取所有文本后,从文本数组创建另一组textView,并将这些textView添加到scrollView或任何父视图中。
然后,您的所有textView的行为都将正常工作。
您甚至可以使用UIPageViewController来呈现文本,以获得漂亮的滑动动画。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接