【问题标题】:NSLayoutManager with multiple NSTextContainers causes UITextViews to not be selectable/editable具有多个 NSTextContainers 的 NSLayoutManager 导致 UITextViews 不可选择/不可编辑
【发布时间】:2015-12-15 04:58:19
【问题描述】:

我正在尝试实现多页文本编辑布局,如 Pages、MS Word、...。在 OS X 上,我可以通过为多个 NSTextViews 创建一个 NSLayoutManager 和一个 NSTextStorage 来实现这一点。每个 NSTextView 都有自己的 NSTextContainer。请参阅下面的 OS X 代码。一个在两个 NSTextView 之间传播文本的简单示例:

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 执行相同操作时,UITextView 变得不可选择或不可编辑。查看我的 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 流向另一个,但不可编辑。我将非常感谢任何建议。我用谷歌搜索了这个问题,发现其他人也遇到了同样的问题,但没有找到解决方案。

【问题讨论】:

  • 你找到解决方案了吗?
  • 我也想知道这个答案。

标签: ios swift uitextview nslayoutmanager nstextcontainer


【解决方案1】:

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

iOS 7 Programming Pushing the Limits: Develop Advance Applications for Apple,第 375 页概述了这个问题:

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

【讨论】:

  • 我观察到的行为略有不同。我的场景是 1 个布局管理器连接到 N 个文本容器。我根据需要从这些 0...N-1 文本容器中生成文本视图。我观察到第 0 个文本视图(第一个)具有 selectable = true。我创建的所有其余部分都有 selectable = false,无论我是否从层次结构中删除了以前的文本视图。相当莫名其妙的行为,可能是设计错误。
【解决方案2】:

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

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

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

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

获取所有文本后,从文本数组创建另一组文本视图,现在将这些文本视图添加到滚动视图或任何父视图中。

您的文本视图的所有行为都将正常工作。

您甚至可以使用 UIPageViewController 来渲染文本以​​获得漂亮的滑动动画。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多