0

I'm resizing the view that a textview belongs to and the text shakes when the view either gets bigger or gets smaller.

Declaration of said text view:

lazy var textview: UITextView = {
        let textView = UITextView()
        textView.text = ""
        textView.font = .systemFont(ofSize: 12, weight: UIFontWeightMedium)
        textView.isScrollEnabled = false
        textView.isEditable = false
        textView.isSelectable = true
        textView.isUserInteractionEnabled = true
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.textAlignment = .center
        textView.textColor = .lightGray
        textView.dataDetectorTypes = .link
        return textView
    }()

I'm resizing the view that it's in to fit the full screen like this

if let window = UIApplication.shared.keyWindow  {
    let statusBarHeight = UIApplication.shared.statusBarFrame.size.height

    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveLinear, animations: {

        self.frame = CGRect(x: 0, y: statusBarHeight, width: window.frame.width, height: window.frame.height - statusBarHeight)

        self.layer.cornerRadius = 0

        self.layoutIfNeeded()

    }, completion: nil)
}

Upon doing so, the view expands perfectly but the textviews text does a bounce effect that makes the animation look extremely unprofessional... any advice?

Edit: It seems like when I remove the center text alignment option it works fine. How do I make it work with the text center aligned?

Walker
  • 1,127
  • 15
  • 39
  • 1
    This is not the cause of the issue, but please note that your code makes no sense. Why are you changing the frame _and_ calling `layoutIfNeeded`? – matt Jan 07 '17 at 16:43
  • @matt removing layoutIfNeeded makes the animation loose smoothness.. I don't know why. Thanks – Walker Jan 07 '17 at 16:56
  • @matt should I remove the textviews constraints, animate the frame.. and then readd them? Everything animates fine it's just the textviews text that does a weird bouncing effect – Walker Jan 07 '17 at 17:37

1 Answers1

0

edit: I took another look at this and attempted to use the technique based in UIScrollView animation of height and contentOffset "jumps" content from bottom.

Here's a minimal working example with text view with centered text alignment which is working for me!

I'd recommend managing animations either to be all constraint based, or all frame based. I attempted a version where the animation is driven by updating the container view frame but it was starting to take too long to left it at this constraint based approach.

Hope this points you in the right direction :)

import UIKit

class ViewController: UIViewController {

    lazy var textView: UITextView = {
        let textView = UITextView()
        textView.text = "testing text view"
        textView.textAlignment = .center
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()

    lazy var containerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    var widthConstraint: NSLayoutConstraint!
    var topAnchor: NSLayoutConstraint!

    override func viewDidLoad() {

        view.backgroundColor = .groupTableViewBackground

        // add container view and constraints
        view.addSubview(containerView)
        containerView.frame = view.bounds.insetBy(dx: 100, dy: 200)
        containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        containerView.heightAnchor.constraint(equalToConstant: 100).isActive = true

        // keep reference to topAnchor and width as properties to animate
        topAnchor = containerView.topAnchor.constraint(lessThanOrEqualTo: view.topAnchor, constant: 100)
        widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 300)
        topAnchor.isActive = true
        widthConstraint.isActive = true

        // add text view to container view and set constraints
        containerView.addSubview(textView)
        textView.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
        textView.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
        textView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        textView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
    }

    @IBAction func toggleResize(_ sender: UIButton) {

        sender.isSelected = !sender.isSelected

        view.layoutIfNeeded()
        widthConstraint.constant = sender.isSelected ? view.bounds.width : 300
        topAnchor.constant = sender.isSelected ? 20 : 100

        // caculate the textView content offset for starting position based on
        // expected end position at end of the animation
        let xOffset = (textView.bounds.width - widthConstraint.constant) / 2
        textView.contentOffset = CGPoint(x: -xOffset, y: textView.contentOffset.y)

        UIView.animate(withDuration: 1) {
            self.view.layoutIfNeeded()
        }
    }
}
Community
  • 1
  • 1
MathewS
  • 2,267
  • 2
  • 20
  • 31
  • Changing the animation while leaving the `self.layoutIfNeeded()` doesn't change anything. Then, removing `self.layoutIfNeeded()` doesn't make the textview bounce but the overall animation looks clunky.. making it even worse... not smooth at all. Any other ideas? Thanks @MathewS – Walker Jan 07 '17 at 16:55
  • the frame I'm updating belongs to a view that in it has a text view and many other views... I don't see how not changing the size of the view and only the text view would solve this – Walker Jan 07 '17 at 17:19
  • I'm updating a view to take up the entire frame and the textview inside of it is getting resized with it... it just has a bounce effect... I want to not have a bounce effect but really just resize the outermost view and let the inner views resize themselves with their constraints – Walker Jan 07 '17 at 17:20
  • please update your question with additional code that gives more context about what's happening, at the moment it's not a complete enough example to understand what's happening – MathewS Jan 07 '17 at 17:21
  • I provided all of the relevant code. I have a view that takes up some space. It has a textview, imageview... some buttons in it. When I resize that view... as in the code above... everything is smooth except the text inside the textview bounces.. as it resizes... I'm not sure what other code to provide that could potentially help other than maybe the entire project lol – Walker Jan 07 '17 at 17:23
  • Ah, I misread the detail in your question that it was the text in the textview that is not smooth. I don't have much experience with animating UITextView, but you might want to try calling `self.textField.invalidateIntrinsicContentSize()` in the animation block. That might help the textview understand that it's internal content view (that the text exists in) needs to reevaluate it's size. – MathewS Jan 07 '17 at 17:31
  • Not a problem. It's extremely weird... I tried what you suggested and it didn't work. Thanks for your time anyways. I really appreciate it – Walker Jan 07 '17 at 17:33
  • I think this might be a related question: http://stackoverflow.com/questions/19311045/uiscrollview-animation-of-height-and-contentoffset-jumps-content-from-bottom (since UITextView is a UIScrollView subclass). There are two answers there you can try, I'd start with trying the `UIViewAnimationOption.beginFromCurrentState` approach first – MathewS Jan 07 '17 at 17:42
  • nothing worked. I just tried removing the text alignment property and it works perfectly... now I need to figure out how to make it work with the center text alignment but atleast I know what's causing it. weird – Walker Jan 07 '17 at 18:20
  • @Walker I updated answer with an approach that's working for me in a demo project – MathewS Jan 07 '17 at 20:42