Ios 如何根据帧的大小分隔UIScrollView/UITextView的字符串

Ios 如何根据帧的大小分隔UIScrollView/UITextView的字符串,ios,xcode,text,uiscrollview,scroll-paging,Ios,Xcode,Text,Uiscrollview,Scroll Paging,我目前正在尝试在RSS提要中阅读,并将长段落文本分离到启用分页的UIScrollView中。我需要将文本分成不同的页面,即适合每个页面的内容,并将字符串分开。我不确定是否有这样做的标准,我假设这就是大多数RSS阅读应用程序在多个页面上分离信息的方式。有人知道如何解决这个问题吗?我不想一个字母一个字母地看,直到文本不适合继续 编辑: 这是一个很好的开始,但是示例代码几乎遇到了我试图避免的问题,并且不知道如何解决。UITextView的此范围计算不正确。我改变了字体,如下图所示。正在尝试在-(NSR

我目前正在尝试在RSS提要中阅读,并将长段落文本分离到启用分页的UIScrollView中。我需要将文本分成不同的页面,即适合每个页面的内容,并将字符串分开。我不确定是否有这样做的标准,我假设这就是大多数RSS阅读应用程序在多个页面上分离信息的方式。有人知道如何解决这个问题吗?我不想一个字母一个字母地看,直到文本不适合继续

编辑:


这是一个很好的开始,但是示例代码几乎遇到了我试图避免的问题,并且不知道如何解决。UITextView的此范围计算不正确。我改变了字体,如下图所示。正在尝试在-(NSRange)visibleRangeOfTextView:(UITextView*)textView中计算所有内容。此方法由-(void)adjustTextDisplay调用,该方法在为UITextView设置文本后由外部类调用。我不知道为什么将内容大小设置为屏幕的帧大小不会限制视图(如下所示),也不知道为什么此方法会返回完整的字符串长度作为范围。

我将完整(从上一页末尾开始)文本设置为textView,而不是繁重的迭代计算。然后很容易执行快速向后搜索来截断单词/句子


我有下面的解决方案,跳过最后一个部分显示的行的一个小技巧部分,以避免滚动并使它看起来更好。您仍然需要移动
endCutIndex
使其成为单词或句子包装

包含寻呼机但不包含文本视图的基本项目取自

下面是.h文件的一部分:

@interface FCContentViewController : UIViewController <UIScrollViewDelegate, UITextViewDelegate>{
    UIPageControl *pageControl;   
    NSString *trunkedString;
    UITextView *bodyText;
}
@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, retain) NSString *bodyTextString;
@接口FCContentViewController:UIViewController{
ui页面控件*页面控件;
NSString*集群字符串;
UITextView*正文;
}
@属性(非原子,保留)UIScrollView*scrollView;
@属性(非原子,保留)NSString*bodyTextString;

我将complete(从上一页的末尾开始)文本设置为textView和。然后很容易执行快速向后搜索来截断单词/句子


我有下面的解决方案,跳过最后一个部分显示的行的一个小技巧部分,以避免滚动并使它看起来更好。您仍然需要移动
endCutIndex
使其成为单词或句子包装

包含寻呼机但不包含文本视图的基本项目取自

下面是.h文件的一部分:

@interface FCContentViewController : UIViewController <UIScrollViewDelegate, UITextViewDelegate>{
    UIPageControl *pageControl;   
    NSString *trunkedString;
    UITextView *bodyText;
}
@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, retain) NSString *bodyTextString;
@接口FCContentViewController:UIViewController{
ui页面控件*页面控件;
NSString*集群字符串;
UITextView*正文;
}
@属性(非原子,保留)UIScrollView*scrollView;
@属性(非原子,保留)NSString*bodyTextString;

从iOS 7开始,我在下面的示例代码中包含了一个使用TextKit的更优雅的解决方案。这样做的目的是让TextKit的布局管理器处理分离字形的问题,并以这种方式正确地布局所有内容。这样可以避免中途断字,并具有很大的灵活性:

class BookView: UIScrollView {

    var bookMarkup: NSAttributedString!
    private let layoutManager = NSLayoutManager()

    override func layoutSubviews() {
        super.layoutSubviews()

        if layoutManager.textContainers.count == 0 {
            buildFrames()
        }
    }

    func buildFrames() {
        let textStorage = NSTextStorage(attributedString: bookMarkup)

        textStorage.addLayoutManager(layoutManager)

        var range = NSMakeRange(0, 0)
        var containerIndex = 0

        while NSMaxRange(range) < layoutManager.numberOfGlyphs {
            let textViewRect = frameForViewAtIndex(containerIndex)
            let containerSize = CGSizeMake(CGRectGetWidth(textViewRect), CGRectGetHeight(textViewRect) - 16) //UITextView adds an 8 margin above and below the container so we take that into consideration here with the 16. heightTracksTextView causes a performance hit when adding multiple containers... so we don't do that instead
            let textContainer = NSTextContainer(size: containerSize)
            layoutManager.addTextContainer(textContainer)

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

            addSubview(textView)

            containerIndex++

            range = layoutManager.glyphRangeForTextContainer(textContainer)
        }

        contentSize = CGSize(width: CGRectGetWidth(bounds) / 2 * CGFloat(containerIndex), height: CGRectGetHeight(bounds))

        pagingEnabled = true
    }

    private func frameForViewAtIndex(index: Int) -> CGRect {

        var textViewRect = CGRect(origin: CGPointZero, size: CGSize(width: CGRectGetWidth(bounds)/2, height: CGRectGetHeight(bounds)))
        textViewRect = CGRectInset(textViewRect, 10, 20)
        textViewRect = CGRectOffset(textViewRect, CGRectGetWidth(bounds) / 2 * CGFloat(index), 0)
        return textViewRect
    }
}
类图书视图:UIScrollView{
var bookMarkup:nsattributestring!
私有let layoutManager=NSLayoutManager()
覆盖func布局子视图(){
super.layoutSubviews()
如果layoutManager.textContainers.count==0{
buildFrames()
}
}
func buildFrames(){
让textStorage=NSTextStorage(attributedString:bookMarkup)
textStorage.addLayoutManager(layoutManager)
var范围=NSMakeRange(0,0)
var containerIndex=0
而NSMaxRange(range)CGRect{
var textViewRect=CGRect(原点:CGPointZero,大小:CGSize(宽度:CGRectGetWidth(边界)/2,高度:CGRectGetHeight(边界)))
textViewRect=CGRectInset(textViewRect,10,20)
textViewRect=CGRectOffset(textViewRect,CGRectGetWidth(边界)/2*CGFloat(索引),0)
返回textViewRect
}
}

从iOS 7开始,我在下面的示例代码中包含了一个使用TextKit的更优雅的解决方案。这样做的目的是让TextKit的布局管理器处理分离字形的问题,并以这种方式正确地布局所有内容。这样可以避免中途断字,并具有很大的灵活性:

class BookView: UIScrollView {

    var bookMarkup: NSAttributedString!
    private let layoutManager = NSLayoutManager()

    override func layoutSubviews() {
        super.layoutSubviews()

        if layoutManager.textContainers.count == 0 {
            buildFrames()
        }
    }

    func buildFrames() {
        let textStorage = NSTextStorage(attributedString: bookMarkup)

        textStorage.addLayoutManager(layoutManager)

        var range = NSMakeRange(0, 0)
        var containerIndex = 0

        while NSMaxRange(range) < layoutManager.numberOfGlyphs {
            let textViewRect = frameForViewAtIndex(containerIndex)
            let containerSize = CGSizeMake(CGRectGetWidth(textViewRect), CGRectGetHeight(textViewRect) - 16) //UITextView adds an 8 margin above and below the container so we take that into consideration here with the 16. heightTracksTextView causes a performance hit when adding multiple containers... so we don't do that instead
            let textContainer = NSTextContainer(size: containerSize)
            layoutManager.addTextContainer(textContainer)

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

            addSubview(textView)

            containerIndex++

            range = layoutManager.glyphRangeForTextContainer(textContainer)
        }

        contentSize = CGSize(width: CGRectGetWidth(bounds) / 2 * CGFloat(containerIndex), height: CGRectGetHeight(bounds))

        pagingEnabled = true
    }

    private func frameForViewAtIndex(index: Int) -> CGRect {

        var textViewRect = CGRect(origin: CGPointZero, size: CGSize(width: CGRectGetWidth(bounds)/2, height: CGRectGetHeight(bounds)))
        textViewRect = CGRectInset(textViewRect, 10, 20)
        textViewRect = CGRectOffset(textViewRect, CGRectGetWidth(bounds) / 2 * CGFloat(index), 0)
        return textViewRect
    }
}
类图书视图:UIScrollView{
var bookMarkup:nsattributestring!
私有let layoutManager=NSLayoutManager()
覆盖func布局子视图(){
super.layoutSubviews()
如果layoutManager.textContainers.count==0{
buildFrames()
}
}
func buildFrames(){
让textStorage=NSTextStorage(attributedString:bookMarkup)
textStorage.addLayoutManager(layoutManager)
var范围=NSMakeRange(0,0)
var containerIndex=0
whi