Uitextview Contentoffset Is Set

UITextView contentOffset is set

i deleted the controller in the storyboard and rebuilt it and it just works now..

UITextView contentOffset changes between viewDidLoad and viewDidAppear

My guess is that when auto layout is applied, the content offset is mangled. This happens right before -layoutSubviews is performed.

So to fix this issue, I could recommend two solutions.

  1. Subclass UITextView and set contentOffset in -layoutSubviews.
  2. Add -viewDidLayoutSubviews to your view controller and set contentOffset for any text views there.

Both of these are kind of hacky workarounds, but are better hacky workarounds than -viewDidAppear: or dispatch_async().


NOTE: Take care to ensure you only adjust the contentOffset in -layoutSubviews or -viewDidLayoutSubviews when appropriate.

UITextView contentOffset on iOS 7

Ok, based on my research and other answers, the problem was the UITextView's content height and not the scrolling to a specific offset. Here is a solution that works the way it should work for iOS 7:

First, you need to recreate the UITextView like this:

    NSString *reqSysVer = @"7.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);

if (osVersionSupported) {

NSLog(@"reset chatoutput");

CGRect outputFrame = self.chatOutput.frame;

[chatOutput removeFromSuperview];
[chatOutput release];
chatOutput = nil;

NSTextStorage* textStorage = [[NSTextStorage alloc] init];
NSLayoutManager* layoutManager = [NSLayoutManager new];
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
[layoutManager addTextContainer:textContainer];
chatOutput = [[UITextView alloc] initWithFrame: outputFrame
textContainer: textContainer];
// if using ARC, remove these 3 lines
[textContainer release];
[layoutManager release];
[textStorage release];

[self.view addSubview: chatOutput];
}

Then, use this method to get the UITextView content height:

- (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width
{
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];

NSLog(@"size: %f", size.height) ;

return size.height;
}

Now you can set the content offset:

CGPoint bottomOffset;

bottomOffset = CGPointMake(0, [self textViewHeightForAttributedText: self.chatOutput.attributedText andWidth: self.chatOutput.frame.size.width] - self.chatOutput.frame.size.height);

[self.chatOutput setContentOffset:bottomOffset animated:YES];

UPDATE

I've read this in the Apple Documentation for NSAttributedString:
"The default font for NSAttributedString objects is Helvetica 12-point, which may differ from the default system font for the platform."

In conclusion, if you use different fonts of different sizes, you have to set those to the NSAttributeString instance as well. Otherwise, the returned height won't correspond to your expectations. You may want to use something like this:

    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject: [UIFont systemFontOfSize: 18.0] //or any other font or size
forKey: NSFontAttributeName];
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: currentPost.postMessageText attributes: attrsDictionary];
frame.size.height = [self textViewHeightForAttributedText: attributedString andWidth: 280.0];
[attributedString release];

UITextView content offset changes after setting frame

Setting textView.scrollable = NO lets me resize the text view without any strange offsets, that's the only way I've been able to figure out. And I guess it's not too much of a limitation for common scenarios, if you want the text view to be scrollable you probably don't need to resize it on the fly since the user can scroll around as the content changes.

UITextView starts at Bottom or Middle of the text

That did the trick for me!

Objective C:

[self.textView scrollRangeToVisible:NSMakeRange(0, 0)];

Swift:

self.textView.scrollRangeToVisible(NSMakeRange(0, 0))

Swift 2 (Alternate Solution)

Add this override method to your ViewController

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textView.setContentOffset(CGPointZero, animated: false)
}

Swift 3 & 4 (syntax edit)

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

textView.contentOffset = .zero
}

Add constraints to UITextView change contentOffset

In layoutSubviews if UIView and in viewDidLayoutSubview ad the below line:

[textview setContentOffset:CGPointMake(0,0)];

This worked for me.



Related Topics



Leave a reply



Submit