Multiple NSTextContainers do not work properly with UIPageViewController

451 views Asked by At

I have a long text (multiple screen pages) stored in an NSTextStorage. I instantiate an NSLayoutManager() and add the textStorage to it. Then I keep adding NSTextContainers of specific size until I use up the whole text. The containers are also added to an array. The idea is that this gets only calculated once so I can later only work with the containers (pages).

This is all part of a model class, which is instantiated in the UIPageViewController. UIPageViewController presents ViewControllers that contain only a UITextView and has a reference to the model. UITextView gets instantiated using an NSTextContainer from an array described above.

This all works well, the problem is, it only works once. Once I "turn" a page, the other page is blank. When I am in landscape, I get two ViewControllers and they both load up correctly. Again, once I turn a page, the textView is empty.

It works perfectly when I create new NSTextStorage, NSLayoutManager and the NSTextContainers every time the page is turned, however, that`s awefully slow and inefficient.

Any idea what could be the cause?

EDIT:

This is creating the textView on a page created by UIPageViewController:

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

And this is in the model instantiated by the UIPageViewController, called by the code above:

    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)
}
0

There are 0 answers