Reputation: 70997
Is it possible to change the content offset of a UITextView so when the user moves from portrait to landscape (or vice versa), the text which is visible to them remains the same?
So if the user was at (in portrait mode)
....some text....
....some text2....
....I'm here.... //this is the visible area
....more text....
moves to landscape, it should be
....some text....some text2....
....I'm here....more text.... //this is the visible area
.....
The UITextView is non-editable but scrollable.
Upvotes: 4
Views: 821
Reputation: 8006
Here you have a short, self contained, compilable example :
import UIKit
class ViewController: UIViewController {
var textView: UITextView!
var percentOfScroll:CGFloat = 0
override func viewDidLoad() {
self.textView = UITextView(frame: CGRectZero)
self.textView.layer.borderColor = UIColor.blackColor().CGColor
self.textView.layer.borderWidth = 1
self.textView.editable = false
self.textView.text = "Lorem ipsum... some longish text"
self.view.addSubview(self.textView)
let leftConstraint = NSLayoutConstraint(item: self.textView, attribute: .Leading, relatedBy: .Equal, toItem: self.view, attribute: .Leading, multiplier: 1, constant: 10)
let rightConstraint = NSLayoutConstraint(item: self.textView, attribute: .Trailing, relatedBy: .Equal, toItem: self.view, attribute: .Trailing, multiplier: 1, constant: -10)
let topConstraint = NSLayoutConstraint(item: self.textView, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 44)
let centerConstraint = NSLayoutConstraint(item: self.textView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1, constant: 0)
self.textView.translatesAutoresizingMaskIntoConstraints = false
self.view.addConstraints([leftConstraint, rightConstraint, topConstraint, centerConstraint])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let contentSize = self.textView.contentSize
let newOffset = contentSize.height * percentOfScroll
self.textView.contentOffset = CGPoint(x: 0, y: newOffset)
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
let contentSize = self.textView.contentSize
let contentOffset = self.textView.contentOffset
self.percentOfScroll = contentOffset.y / contentSize.height
}
}
The idea is to get the amount of scrolled content in relation to its height before rotation (viewWillTransitionToSize
) and using it calculate new contentOffset
after (viewDidLayoutSubviews
is also called after size change).
Bear in mind that this doesn't give a 100% precise result, but I haven't been able to come up with anything better , and maybe this will be enough for you.
Upvotes: 4