Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextview is getting randomly clipped when using Autolayout and or preferredFontForTextStyle

Autolayout will randomly clip the text in my UITextView. It changes the size of the UITextContainerView when you rotate back and forth from landscape to portrait. It will work correctly several times but will randomly change the container and clip the static text.

If I disable Autolayout then the issue goes away. It also seems to go away if I eliminate the preferredFontForTextStyle code and keep the Autolayout.

The thing is I wanted to allow the user to set the text size and be able to use auto layout. The text is all static so this should be a simple thing.

Has anyone seen this? Is this a bug or have to do something incorrectly?

I have reduced the code to as small as I could in order to try and isolate the problem.

Here is the code

//  BugTest_ViewController.h
//
//
//
//

#import <UIKit/UIKit.h>

@interface BugTest_ViewController : UIViewController



@property (weak, nonatomic) IBOutlet UIImageView *image1;

@property (weak, nonatomic) IBOutlet UITextView *text1;



@end

//  BugTest_ViewController.m
//
//
//  
//

#import "BugTest_ViewController.h"

@interface BugTest_ViewController ()


@end

@implementation BugTest_ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
   
}

-(void)viewWillAppear:(BOOL)animated
{

    self.text1.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
    [self.text1 setContentOffset:CGPointZero animated:YES];
    
}

Here is the container when the view looks as it should Good Container

Here is the container when the view is being clipped. Bad Container clipping my text

like image 580
user3259366 Avatar asked Jan 25 '16 00:01

user3259366


2 Answers

The solution from this question helps me. I write something like this:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    _textView.scrollEnabled = NO;
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        _textView.scrollEnabled = YES;
    }];
}
like image 148
Andrew Egorov Avatar answered Oct 19 '22 20:10

Andrew Egorov


The reason seems to be that a transformation applied to a UITextView can sometimes corrupt the view's dynamic layout. A screen rotation effectively applies rotation and translation transformations to the views during the transition.

The same issue happens when CGAffineTransform is applied to a UITextView. Here is a visual example where the _UITextContainerView (blue frame) is smaller than the UITextView (green background) after a CGAffineTransform, causing the text to be appear cropped.

enter image description here

One solution that worked in this case was to set the content inset after the transformation has finished:

textView.contentInset = .zero
view.layoutIfNeeded()
like image 33
Manuel Avatar answered Oct 19 '22 21:10

Manuel