17

The issue is to move an "InfoView" (UIView) programmatically in Swift.

The following constraints exist in the storyboard (see image):

enter image description here

Now, I would like to move the "InfoView" inside "MyView" up or down.

I tried:

@IBOutlet weak var infoTextLabel: UILabel!
@IBOutlet weak var infoTextLabelView: UIView!

// set infoTextLabel color
self.infoTextLabel.textColor = UIColor.blackColor()
// set infoTextLabel text
self.infoTextLabel.text = "hello"
// unhide infoTextLabel
self.infoTextLabel.hidden = false

// For the moving in Y-direction, I tried this - but does not work !!!!!!!
self.infoTextLabelView.frame.origin.y += 200

Could the Autolayout-constraints play a role. How to overcome those programmatically. Or is the frame.origin.y method the wrong one ??

Appreciate any help on this !

iKK
  • 6,394
  • 10
  • 58
  • 131

4 Answers4

25

When using constraints, you never want to set a view's frame directly. Instead, reconfigure the constraints and let the auto layout engine set your view's frame for you. Create an IBOutlet in your view controller to store a reference to your "Center Y Alignment constraint". Make sure you connect it in your storyboard or xib.

@IBOutlet var yConstraint: NSLayoutConstraint

Then you can set the constraint's constant property to offset it from the Y position (positive number will move it down, negative moves it up).

yConstraint.constant = 200

This would move your view 200 points down.

Darren Findlay
  • 2,533
  • 2
  • 29
  • 46
17

See my answer to this other question about a good way to programmatically move views using auto layout: https://stackoverflow.com/a/30687856/3149796

Also, depending on the effect you're going for and other requirements of your UI, you might also achieve this with transforms without disturbing your auto layout.

// Create a new transform
self.infoTextLabelView.transform = CGAffineTransformMakeTranslation( 0.0, 200.0 )

// Or modify existing transform
self.infoTextLabelView.transform = CGAffineTransformTranslate( self.infoTextLabelView.transform, 0.0, 200.0  )
Community
  • 1
  • 1
Patrick Lynch
  • 2,742
  • 1
  • 16
  • 18
  • Make sure you turn off the AutoResizing constraints or the second option doesn't work. – Dan M Feb 22 '21 at 21:50
  • I'm not sure what you mean by this, dan m. To this day, both examples appear to work as intended. Could you be more specific? – Patrick Lynch Feb 23 '21 at 22:20
9

Swift 4

UIView.animateKeyframes(withDuration: 0.25, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: 7), animations: {
       self.infoTextLabelView.frame.origin.y+=200

},completion: nil)
Niall Kiddle
  • 1,477
  • 1
  • 16
  • 35
ZAFAR007
  • 3,049
  • 1
  • 34
  • 45
  • what is rawValue: 7 means? – Yaroslav Dukal Jul 20 '18 at 04:38
  • Swift 5 - UIView.animateKeyframes(withDuration: 0.25, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: 7), animations: { self.infoTextLabelView.frame.origin.y+=200 },completion: nil) – Roney Sampaio May 08 '19 at 08:39
  • Or even something simple like this ?: UIView.animate(withDuration: 0.1) { self.formSV.frame.origin.y += 100 } – Marcos Aug 13 '19 at 16:57
  • This works for me with the same result: UIView.animateKeyframes(withDuration: 2.0, delay: 0.0, animations: { self.infoTextLabelView.frame.origin.y+=200 },completion: nil) – 7RedBits.com May 29 '20 at 10:18
8

Swift 5

Use CGAffineTransform

@IBOutlet weak var mainCurtain: UIView!

func moveUp() {
    UIView.animate(withDuration: 0.5, delay: 0.0, options:[], animations: {
        self.mainCurtain.transform = CGAffineTransform(translationX: 0, y: 0)
    }, completion: nil)
}


func moveDown() {
    UIView.animate(withDuration: 0.5, delay: 0.0, options:[], animations: {
        let screenSize = UIScreen.main.bounds.size
        self.mainCurtain.transform = CGAffineTransform(translationX: 0, y: screenSize.height * 0.5)
    }, completion: nil)
}