19

When I apply a rotation transform to a UITextView and then click inside to begin editing, it appears that the content size is automatically being made wider. The new width of the content view is the width of the rotated view's bounding box. For example, given a text box of width 500 and height 400, and rotated by 30 degrees, the new content width would be:

(500 * cos(30)) + (400 * sin(30)) = 633

Or graphically:

enter image description here

Interestingly, if you are already editing the text view and THEN apply the transform, then it appears that no modification is made to the content size. So it appears that sometime around the start of text editing, the text view looks at its frame property and adjusts the content size based on the frame width. I imagine the solution to this is to tell it to use the bounds property instead, however I don't know where to do this, as I'm not sure exactly where the text view is deciding to modify the content size.

I have googled but can't seem to find any references to using transformed UITextViews. Does anybody have any ideas about this?

EDIT (button action from test project):

- (IBAction)rotateButtonTapped:(id)sender {
    if (CGAffineTransformIsIdentity(self.textView.transform)) {
        self.textView.transform = CGAffineTransformMakeRotation(30.0 * M_PI / 180.0);
    }
    else {
        self.textView.transform = CGAffineTransformIdentity;
    }

    NSLog(@"contentsize: %.0f, %.0f", textView.contentSize.width, textView.contentSize.height);
}
Stuart
  • 36,683
  • 19
  • 101
  • 139
  • Sounds like you've uncovered a bug. Have you posted this in the Apple devforums, or created a [bugreport](http://bugreport.apple.com)? – RyanR Jun 25 '11 at 23:09
  • Not yet, I was hoping it was an oversight I suppose. Apple's own Keynote app for iPad appears to use transformed UITextViews easily enough. Either it's a strange bug or there's a subtle trick to it. I'll post in the dev forums, and if nobody can offer any suggestions there I'll file a bug report. – Stuart Jun 25 '11 at 23:15
  • Have you tried implementing the UIScrollViewDelegate methods on your textView delegate, just to see if any of them are being called unexpectedly and maybe giving a 'zoomed' view? I'm grasping at straws, but it's the only thing I can think of. – RyanR Jun 25 '11 at 23:22
  • Any help is appreciated, thanks. I hadn't played around with the UIScrollViewDelegate methods, but have just done so and nothing seems out of order - zoomScale remains at 1.0 throughout. I had tried the UITextViewDelegate methods and they showed that at the time of calling `-textViewDidBeginEditing:' on the rotated text view, the content size was still as it should be. Everything following this call shows the larger content size, even after rotating back to the identity transform. – Stuart Jun 25 '11 at 23:44
  • Do you have a sample project you can share that demonstrates this? I have a contact in one of the bigger iOS development shops, I can ask if they have a solution to it. I might need the same functionality in a future project I'm planning, just so you know I'm not completely altruistic :) – RyanR Jun 25 '11 at 23:51
  • Haha, sure no problem :). To be honest the sample project is incredibly simple. Hook up a standard UITextView in IB (and assign to an outlet), add a round rect button and hook up to fire the action posted in the edit above. – Stuart Jun 25 '11 at 23:55

2 Answers2

24

I was also stuck with this problem.

The only solution which I found was to create an instance of UIView and add the UITextView as a subview. Then you can rotate the instance of UIView and UITextView will work just fine.

UITextView *myTextView = [[UITextView alloc] init];
[myTextView setFrame:CGRectMake(0, 0, 100, 100)];

UIView *myRotateView = [[UIView alloc] init];
[myRotateView setFrame:CGRectMake(20, 20, 100, 100)];
[myRotateView setBackgroundColor:[UIColor clearColor]];
[myRotateView addSubview:myTextView];

myRotateView.transform = CGAffineTransformMakeRotation(0.8);
[[self view] addSubview:myRotateView];
Armands Antans
  • 478
  • 4
  • 13
  • So helpful! Thank you for posting! – Suragch Feb 27 '15 at 08:27
  • Thank you for this answer! I had quiet a few problems with getting a NSTextView to display vertically flipped text. The enclosing scroll view would just go berserk whenever I applied any form of transform to the text view. Your answer solved this mess for me. Just transform the superview. Thanks! –  Mar 05 '16 at 16:55
1

Have you tried applying the rotation by doing a layer transform rather than a transform on the view?

#import <QuartzCore/QuartzCore.h>

mytextField.layer.transform = CATransform3DMakeRotation (angle, 0, 0, 1);

This might be enough to trick whatever broken logic exists inside the core text field code.

gdawg
  • 721
  • 6
  • 5
  • A sensible suggestion, but unfortunately it doesn't solve the problem. – Stuart Sep 23 '11 at 08:35
  • 1
    ergh that's unfortunate ;( You could always put the text view inside another view then rotate the parent instead to see if that helps but it's sounding more and more like you might need a fix from Apple. – gdawg Sep 27 '11 at 23:16
  • Wrapping inside another view hadn't even crossed my mind - how simple but effective. It's unfortunate as I can't really afford placing more views where they shouldn't be necessary, however it at least provides something workable for the time being. A fix is needed for this issue, and I filed a bug report a couple of months ago (which included the bug on the latest iOS 5 beta). Thanks for your suggestions. – Stuart Sep 28 '11 at 15:05