如何在ios中限制UITextView中的内容

时间:2014-02-08 10:00:16

标签: ios split pagination uitextview

我想在不同视图的TextViews中加载长文本。文本视图结束时,文本应分为页面。下一个textview必须从文本的继续开始。

我经历了很多答案。但是所有都指定了在输入数据时限制文本内容。我想在TextView中显示分页数据。并且不会有任何输入或编辑。因此,关于它的委托方法将不起作用。

我尝试加载固定长度的文本。但是当段落的编号不同时,这是不正确的。

所以我想要找到的是,当文本到达textview的容量结束时获得通知,或者根据no lines / no.of字符获得textview的容量。有没有办法做到这一点?

更新

根据我的评论,我搜索了很多,并在NSTextStorage,NSTextLayoutManager和NSTextContainer

我找到了这个有助于轻松实现分页的链接

  
    

http://sketchytech.blogspot.co.uk/2013/11/paging-and-paginating-easy-way-with.html

  

我在这个例子中他们使用循环创建了4个对象。可以这么说,因为他们将字符串拆分为4个部分,并在滚动视图的4个uitextviews中显示。

我正在尝试根据字符串的长度设置拆分为textcontainers的条件。 我试图通过考虑主弦和弦的总长度来创建一个条件。 textview中显示的文字。

enter image description here

但每个textview的文本长度与主字符串的总长度相同。那么我如何才能在textview ????

的每个文本容器中显示长度文本

7 个答案:

答案 0 :(得分:3)

您可以创建CTFramesetter并调用CTFramesetterSuggestFrameSizeWithConstraints。然后,您将找到适合给定CGSize的文本范围。 然后根据范围操作文本,您就完成了。

参考 - CoreText

答案 1 :(得分:2)

我不得不在UITextView中对文本进行测量,以便在iOS 5上的UITextView中覆盖某些单词之上的视图。随着iOS 7的UITextView更改,我不再需要这样做。我测量的方式可能是你需要分解你的文字。我没有一个好的工作代码,所以我必须尽可能地记住算法。

当存在可变线高时,此算法不起作用。

  1. 我通过试验错误发现我需要匹配的文字宽度是文字视图的宽度减去16。
  2. 对文本的子字符串进行二进制搜索,以找到适合UITexView的最大子字符串,其中子字符串在字边界处断开。您可以使用NSLinguistic标记符来获取字边界。
  3. 在每个子串调用[substr sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:NSLineBreakByWordWrapping]上,其中大小限制在步骤1的宽度和非常大的高度。
  4. 您需要继续搜索,直到您可以识别单词边界,其中带有约束的字体大小为您提供适合您视图的高度,紧接着的下一个单词会为您提供一个不适合您视图的高度。您将知道这是UITextView将进行自动换行的地方,这个换行太大而无法放在您的某个页面上。
  5. 在步骤4的单词边界上中断文字,并为下一页做同样的事情。

答案 2 :(得分:1)

这是两个要素:

使用ios 7文本工具包的多列的一个很好的解释/示例:

https://github.com/ShinobiControls/iOS7-day-by-day/blob/master/21-multi-column-textkit/21-multi-column-textkit.md

基于该样本和以下问题:

How do I locate the CGRect for a substring of text in a UILabel?

你可以尝试这样的事情:

- (void)layoutTextContainers
{
    NSUInteger lastRenderedGlyph = 0;
    CGFloat currentXOffset = 0;
    while (lastRenderedGlyph < _layoutManager.numberOfGlyphs) {
        CGRect textViewFrame = CGRectMake(currentXOffset, 10,
                                          CGRectGetWidth(self.view.bounds) / 2,
                                          CGRectGetHeight(self.view.bounds) - 20);
        CGSize columnSize = CGSizeMake(CGRectGetWidth(textViewFrame) - 20,
                                       CGRectGetHeight(textViewFrame) - 10);

        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:columnSize];
        [_layoutManager addTextContainer:textContainer];

        // And a text view to render it
        UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame
                                                   textContainer:textContainer];
        textView.scrollEnabled = NO;
        [self.scrollView addSubview:textView];



        // Increase the current offset
        currentXOffset += CGRectGetWidth(textViewFrame);

        // And find the index of the glyph we've just rendered
        lastRenderedGlyph = NSMaxRange([_layoutManager glyphRangeForTextContainer:textContainer]);

        NSLog(@"Last rendered glyph %i",lastRenderedGlyph);

        NSLog(@"Textview length %i",textView.text.length);

        NSRange range = {lastRenderedGlyph-1, lastRenderedGlyph};

        NSRange glyphRange;

        // Convert the range for glyphs.
        [_layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange];

        NSLog(@"Glyph rect %@",NSStringFromCGRect([_layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer]));
    }

    // Need to update the scrollView size
    CGSize contentSize = CGSizeMake(currentXOffset, CGRectGetHeight(self.scrollView.bounds));
    self.scrollView.contentSize = contentSize;
}

输出是:

 Newspaper[89217:a0b] Last rendered glyph 711
 Newspaper[89217:a0b] Textview length 2585
 Newspaper[89217:a0b] Glyph rect {{121.556, 515.3761}, {13.444, 14.315979}}
 Newspaper[89217:a0b] Last rendered glyph 1441
 Newspaper[89217:a0b] Textview length 2585
 Newspaper[89217:a0b] Glyph rect {{129.15199, 515.3761}, {5.8480072, 14.315979}}
 Newspaper[89217:a0b] Last rendered glyph 2155
 Newspaper[89217:a0b] Textview length 2585
 Newspaper[89217:a0b] Glyph rect {{111.80001, 515.3761}, {23.199989, 14.315979}}
 Newspaper[89217:a0b] Last rendered glyph 2585
 Newspaper[89217:a0b] Textview length 2585
 Newspaper[89217:a0b] Glyph rect {{92.720001, 329.26801}, {3.552002, 14.31601}}

Glyph Rect看起来不太好(我很想看到它正常工作) 但是你显示最新的字形

希望它有所帮助!

答案 3 :(得分:0)

如何将总文本分配给所有文本视图。然后,当我们从一个文本移动到另一个文本视图时,我们只使用文本视图的以下功能。

- (void)scrollRangeToVisible:(NSRange)range;

您将决定最初应该是什么范围,然后在每次迭代时继续更改它,直到您到达字符串结尾。

答案 4 :(得分:0)

我使用库DTCoreText做了类似的事情。

DTCoreText包含布局助手,可以轻松剪切列中的文本并创建不同的文本视图。我在github上创建了一个示例,展示了如何完成:

https://github.com/brovador/DTCoreTextColumnsExample

希望有所帮助

答案 5 :(得分:0)

选项2在iOS中可以使用适当的参数。

NSAttributedString *attrStr = ... // your attributed string
CGFloat width = 300; // whatever your desired width is
CGRect rect = [attrStr boundingRectWithSize:CGSizeMake(width, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];

如果没有适当的options参数值,您将获得错误的高度。

here

得到了这个答案

答案 6 :(得分:-1)

使用以下方法:

 NSString *textEntered = [[[tvQuestion.text copy] autorelease] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

        //Added for 450 character restriction 
        if([textEntered length] > 450) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Message" message:kMoreThan450CharactersForQuestion delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
            [alertView release];
        }