我有一个长文本(多个屏幕页面)存储在NSTextStorage中。我实例化一个NSLayoutManager()并将textStorage添加到它。然后我继续添加特定大小的NSTextContainer,直到我用完整个文本。容器也被添加到阵列中。这个想法是,这只计算一次,所以我以后只能使用容器(页面)。
这是模型类的所有部分,它在UIPageViewController中实例化。 UIPageViewController提供了仅包含UITextView的ViewControllers,并且具有对模型的引用。 UITextView使用上述数组中的NSTextContainer进行实例化。
这一切都很好,问题是,它只能工作一次。一旦我转向"一个页面,另一页是空白的。当我在横向时,我得到两个ViewControllers,他们都正确加载。再次,当我翻页时,textView为空。
当我每次翻页时创建新的NSTextStorage,NSLayoutManager和NSTextContainers时,它的工作非常完美,但是,这非常缓慢且效率低下。
知道可能是什么原因?
编辑:
这是在由UIPageViewController创建的页面上创建textView:
func reloadData() {
let rect = CGRect(
x: view.bounds.origin.x + spacing,
y: view.bounds.origin.y + spacing,
width: view.bounds.width - spacing * 2,
height: view.bounds.height - spacing * 2)
if let textContainer = bookReader.getPage(pageIndex, frame: rect) {
textView = UITextView(frame: rect, textContainer: textContainer)
textView!.textAlignment = textAlignment
textView!.editable = false
lastSize = textView!.frame
view.addSubview(textView!)
} else {
print("did't get a page")
}
}
这是在由UIPageViewController实例化的模型中,由上面的代码调用:
func getPage(page: Int, frame: CGRect) -> NSTextContainer? {
// if the screen size was changed (rotated) erase everything
if self.lastFrame != frame {
print("size was changed")
chapters.removeAll()
self.lastFrame = frame
}
// if the data has been already calculated
if chapters.count > 0 {
// find chapter and page (this part is not working correctly yet but that doesn`t really matter in this case, it just fetches wrong page in some cases)
var chapter = 0
var subPage = 0
var checkedPages = 0
for i in 0..<chapters.count {
if page - 1 < (i + 1) * chapters[i]!.count {
chapter = i
subPage = page - 1 - checkedPages
break
} else {
checkedPages += chapters[i]!.count
}
}
print("desired page: \(page) - chapter: \(chapter), page: \(subPage)")
// return textContainer
if let textContainer = chapters[chapter]?[subPage] {
print("the container is in the array")
return textContainer
} else {
print("page couldn't been found")
return nil
}
} else {
// calculate the whole book
numberOfPages = 0
for (index, url) in htmls.enumerate() {
let data = NSData(contentsOfURL: url)
let attributedString = NSAttributedString(HTMLData: data, options: options, documentAttributes: nil)
let textStorage = NSTextStorage(attributedString: attributedString)
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
var i = 0
while layoutManager.textContainerForGlyphAtIndex(textStorage.length - 1, effectiveRange: nil) == nil {
let textContainer = NSTextContainer(size: frame.size)
layoutManager.addTextContainer(textContainer)
if chapters[index] != nil {
chapters[index]![i] = textContainer
} else {
chapters[index] = [i:textContainer]
}
i++
}
numberOfPages += i - 1
print("chapter \(index) count \(chapters[index]!.count)")
}
}
print("recursive call, number of pages: \(numberOfPages)")
return getPage(page, frame: frame)
}