1

Here's how it seems to me the code I'm dealing with ought to be written:

    if (!instructions)
{
    instructions = [[UITextView alloc] init];
    instructions.backgroundColor=[UIColor clearColor];
    instructions.font = [UIFont fontWithName:@"Helvetica Neue" size:12];
    instructions.editable=NO;
    instructions.text = @"\nFor millennia, the Japanese haiku has allowed great\nthinkers to express their ideas about the world in three\nlines of five, seven, and five syllables respectively.";

//THIS IS THE RELEVANT LINE:
    NSString *t = @"thinkers to express their ideas about the world in three"; //Using this to set width since it's the longest line of the string.

    CGSize thisSize = [t sizeWithFont:[UIFont fontWithName:@"Helvetica Neue" size:12]];
    float textWidth = thisSize.width;
    const int INSTRUCTIONS_HEIGHT=10; //I know this is an ugly hack.
    float textHeight = thisSize.height*INSTRUCTIONS_HEIGHT;
    instructions.frame = CGRectMake(screenWidth/2-textWidth/2, screenHeight/2-textHeight/2, textWidth, textHeight);
}

But the output looks like this, with the line having to wrap around:

enter image description here

When I adjust the code to add a few characters to the line setting the width:

    {
    instructions = [[UITextView alloc] init];
    instructions.backgroundColor=[UIColor clearColor];
    instructions.font = [UIFont fontWithName:@"Helvetica Neue" size:12];
    instructions.editable=NO;
    instructions.text = @"\nFor millennia, the Japanese haiku has allowed great\nthinkers to express their ideas about the world in three\nlines of five, seven, and five syllables respectively.";

//THIS IS THE LINE I CHANGED:
    NSString *t = @"thinkers to express their ideas about the world in three lin"; //

    CGSize thisSize = [t sizeWithFont:[UIFont fontWithName:@"Helvetica Neue" size:12]];
    float textWidth = thisSize.width;
    const int INSTRUCTIONS_HEIGHT=6; //Since there's no wraparound here I could reduce this number.
    float textHeight = thisSize.height*INSTRUCTIONS_HEIGHT;
    instructions.frame = CGRectMake(screenWidth/2-textWidth/2, screenHeight/2-textHeight/2, textWidth, textHeight);
}

the output looks like what I want:

enter image description here

Why does the line "thinkers to express their ideas about the world in three" not fit into a text view set at the width of the line "thinkers to express their ideas about the world in three"?

(Obviously I have some learning to do about ways to orient things on screen. I haven't figured out "center" yet, for example, which I suspect would solve a lot of my problems. But this is what I'm working with for now, and I'm curious.)

Joel Derfner
  • 2,207
  • 6
  • 33
  • 45

3 Answers3

3

UITextView by default has some padding. You can get rid of it if you want: How to lose margin/padding in UITextView?

Community
  • 1
  • 1
Patrick Tescher
  • 3,387
  • 1
  • 18
  • 31
  • Weirdly, the approach suggested in that question, which should work, still gives me the wraparound-too-early problem. For now I'm just going to stick with what I have (adding the three characters), but I'm going to file this away as a problem to consider further. – Joel Derfner Jan 15 '13 at 01:18
3

You need to constrain the sizeWithFont to the width of the text view.

Something like:

drawnSize = [t sizeWithFont:[UIFont fontWithName:@"Helvetica Neue" size:12]
                 constrainedToSize:CGSizeMake(instructions.frame.size.width, 3000)
                 lineBreakMode:NSLineBreakByWordWrapping ] ;

You may also need to obtain the insets from the text view and subtract them from the width:

UIEdgeInsets edgeInsets = instructions.contentInset;
CGFloat totalwidth = instructions.frame.size.width - edgeInsets.left - edgeInsets.right;
jsd
  • 7,673
  • 5
  • 27
  • 47
  • 1
    Yes, I too would suggest using constraints. However, that does not fix the issue of UITextView having some insect (for the scroll bar etc.) – Hermann Klecker Jan 15 '13 at 00:25
  • You're right, you may also need to find the textview's contentInset property and subtract the left and right insets from the width. – jsd Jan 15 '13 at 00:27
  • @jsd `contentInset property` how? – zaph Jan 15 '13 at 00:30
  • @jsd I do not see `contentInset` for `UITextView`. Only for `UIScrollView` and `UIPrintFormatter`. Can you provide the Apple docs for `UITextView`? – zaph Jan 15 '13 at 01:00
  • UITextView is a subclass of UIScrollView. See http://developer.apple.com/library/ios/#documentation/uikit/reference/uitextview_class/Reference/UITextView.html – jsd Jan 15 '13 at 01:03
  • Weirdly, this approach, which should work, still gives me the wraparound-too-early problem. For now I'm just going to stick with what I have (adding the three characters), but I'm going to file this away as a problem to consider further. Thanks for your thoughts. – Joel Derfner Jan 15 '13 at 01:17
  • @JoelDerfner, I think this approach is correct, but even when contentInset is 0, there is about 10 to 12 points on each edge of apparent inset (as measured on my phone or the simulator). So, if you use (drawnSize.width +24) as your width, things should work out as you intend. – rdelmar Jan 15 '13 at 05:32
  • @rdelmar Yup, that did it. `textWidth = thisSize.width + 16 and everything is pretty again! – Joel Derfner Jan 15 '13 at 12:38
3

One reason is that you are using text views. What you do would work fine for UILabel. And Labels may have multiple lines. So if you donnot really need the text view for scrolling the text then consider using lables instead.

I don't remember the exact value. But for a text view consider some fuzzy insect value by which the actual width/space for the text itself is smaller than the text view with.

Hermann Klecker
  • 14,039
  • 5
  • 48
  • 71
  • A label isn't really going to work for what I'm doing, and fuzzy inset values have thus far proven unhelpful. For now I'm just going to stick with what I have (adding the three characters), but I'm going to file this away as a problem to consider further. – Joel Derfner Jan 15 '13 at 01:18
  • Thanks, though--I do appreciate the advice. – Joel Derfner Jan 15 '13 at 12:39