使用UITextView进行动态分页

时间:2017-05-31 10:39:56

标签: ios swift swift3 pagination uitextview

我正在尝试使用UITextView从左到右创建动态分页滚动。我已经使用本教程实现了一个代码: http://sketchytech.blogspot.com/2013/11/paging-and-paginating-easy-way-with.html

这是我的代码:

let pageNumber: CGFloat = 4.0

override func viewDidLoad() {

    super.viewDidLoad()
    let scrollingView = UIScrollView(frame: CGRect(x: CGFloat(20), y: CGFloat(20), width: CGFloat(view.bounds.size.width - 20), height: CGFloat(view.bounds.size.height - 20)))
    scrollingView.contentSize = CGSize(width: CGFloat((view.bounds.size.width - 20) * pageNumber), height: CGFloat(view.bounds.size.height - 20))
    scrollingView.isPagingEnabled = true
    view.addSubview(scrollingView)

    let textString = "NOW, what I want is, Facts.  Teach these boys and girls nothing but Facts.  Facts alone are wanted in life.  Plant nothing else, and root out everything else.  You can only form the minds of reasoning animals upon Facts: nothing else will ever be of any service to them.  This is the principle on which I bring up my own children, and this is the principle on which I bring up these children.  Stick to Facts, sir!’ The scene was a plain, bare, monotonous vault of a school-room, and the speaker’s square forefinger emphasized his observations by underscoring every sentence with a line on the schoolmaster’s sleeve.  The emphasis was helped by the speaker’s square wall of a forehead, which had his eyebrows for its base, while his eyes found commodious cellarage in two dark caves, overshadowed by the wall.  The emphasis was helped by the speaker’s mouth, which was wide, thin, and hard set.  The emphasis was helped by the speaker’s voice, which was inflexible, dry, and dictatorial.  The emphasis was helped by the speaker’s hair, which bristled on the skirts of his bald head, a plantation of firs to keep the wind from its shining surface, all covered with knobs, like the crust of a plum pie, as if the head had scarcely warehouse-room for the hard facts stored inside.  The speaker’s obstinate carriage, square coat, square legs, square shoulders,—nay, his very neckcloth, trained to take him by the throat with an unaccommodating grasp, like a stubborn fact, as it was,—all helped the emphasis. ‘In this life, we want nothing but Facts, sir; nothing but Facts!’ The speaker, and the schoolmaster, and the third grown person present, all backed a little, and swept with their eyes the inclined plane of little vessels then and there arranged in order, ready to have imperial gallons of facts poured into them until they were full to the brim."

    let textStorage = NSTextStorage(string: textString)
    let textLayout = NSLayoutManager()
    textStorage.addLayoutManager(textLayout)
    textLayout.delegate = self

    var i: Int = 0
    while i <= 4 {
        let textContainer = NSTextContainer(size: scrollingView.frame.size)
        textLayout.addTextContainer(textContainer)
        let textView = UITextView(frame: CGRect(x: CGFloat(scrollingView.frame.size.width * CGFloat(i)), y: CGFloat(0), width: CGFloat(scrollingView.frame.size.width), height: CGFloat(scrollingView.frame.size.height)), textContainer: textContainer)
        textView.font = .systemFont(ofSize: 25)
        textView.tag = i
        scrollingView.addSubview(textView)
        i += 1
    }
}

func layoutManager(_ layoutManager: NSLayoutManager, didCompleteLayoutFor textContainer: NSTextContainer?, atEnd layoutFinishedFlag: Bool) {

    print("called")
}

唯一的问题是此处页面数量是限制的还是用户定义的静态值。但是如果我想将字体大小更改为30则需要额外的页面。在最后的教程中,它说:“为了添加动态元素,你需要利用NSLayoutManager委托方法。”我阅读了NSLayoutManger的文档,发现layoutManager(_:didCompleteLayoutFor:atEnd :)非常适合我在代码中添加但未确定如何利用它的分页。任何人都可以告诉我如何通过更改fontSize使textview动态,它会自动调整所需的页数?

1 个答案:

答案 0 :(得分:2)

我认为您会发现它比预期的容易 - 而且您甚至不需要NSLayoutManagerDelegate

override func viewDidLoad() {

    super.viewDidLoad()

    let scrollingView = UIScrollView(frame: CGRect(x: CGFloat(20), y: CGFloat(20), width: CGFloat(view.bounds.size.width - 40), height: CGFloat(view.bounds.size.height - 40)))

    // we will set the contentSize after determining how many pages get filled with text
    //scrollingView.contentSize = CGSize(width: CGFloat((view.bounds.size.width - 20) * pageNumber), height: CGFloat(view.bounds.size.height - 20))

    scrollingView.isPagingEnabled = true
    view.addSubview(scrollingView)

    let textString = "NOW, what I want is, Facts.  Teach these boys and girls nothing but Facts.  Facts alone are wanted in life.  Plant nothing else, and root out everything else.  You can only form the minds of reasoning animals upon Facts: nothing else will ever be of any service to them.  This is the principle on which I bring up my own children, and this is the principle on which I bring up these children.  Stick to Facts, sir!’ The scene was a plain, bare, monotonous vault of a school-room, and the speaker’s square forefinger emphasized his observations by underscoring every sentence with a line on the schoolmaster’s sleeve.  The emphasis was helped by the speaker’s square wall of a forehead, which had his eyebrows for its base, while his eyes found commodious cellarage in two dark caves, overshadowed by the wall.  The emphasis was helped by the speaker’s mouth, which was wide, thin, and hard set.  The emphasis was helped by the speaker’s voice, which was inflexible, dry, and dictatorial.  The emphasis was helped by the speaker’s hair, which bristled on the skirts of his bald head, a plantation of firs to keep the wind from its shining surface, all covered with knobs, like the crust of a plum pie, as if the head had scarcely warehouse-room for the hard facts stored inside.  The speaker’s obstinate carriage, square coat, square legs, square shoulders,—nay, his very neckcloth, trained to take him by the throat with an unaccommodating grasp, like a stubborn fact, as it was,—all helped the emphasis. ‘In this life, we want nothing but Facts, sir; nothing but Facts!’ The speaker, and the schoolmaster, and the third grown person present, all backed a little, and swept with their eyes the inclined plane of little vessels then and there arranged in order, ready to have imperial gallons of facts poured into them until they were full to the brim."

    let textStorage = NSTextStorage(string: textString)
    let textLayout = NSLayoutManager()
    textStorage.addLayoutManager(textLayout)
    textLayout.delegate = self

    var r = CGRect(x: 0, y: 0, width: scrollingView.frame.size.width, height: scrollingView.frame.size.height)

    var i: Int = 0

    // this is what we'll use to track the "progress" of filling the "screens of textviews"
    // each time through, we'll get the last Glyph rendered...
    // if it's equal to the total number of Glyphs, we know we're done
    var lastRenderedGlyph = 0

    while lastRenderedGlyph < textLayout.numberOfGlyphs {

        let textContainer = NSTextContainer(size: scrollingView.frame.size)
        textLayout.addTextContainer(textContainer)

        let textView = UITextView(frame: r, textContainer: textContainer)

        r.origin.x += r.width

        textView.font = .systemFont(ofSize: 25)

        textView.tag = i

        i += 1

        scrollingView.addSubview(textView)

        // get the last Glyph rendered into the current textContainer
        lastRenderedGlyph = NSMaxRange(textLayout.glyphRange(for: textContainer))

    }

    // use the last textView rect to set contentSize
    scrollingView.contentSize = CGSize(width: r.origin.x, height: r.size.height)

    print("Actual number of pages =", i)
}

改变字体大小并更改实际文字... 看到页面计数自动填充。