1

I've been stuck with this problem for quite some time now. When developing iOS applications in objective-c, how can we programmatically change the position (location) of UIViews when Autolayout is enabled? It's so easy without Autolayout since we just specify a new center for the UIView as such:

UIView.center = CGPointMake(x,y);

However, the above no longer works because of Autolayout. Ultimately, I'm trying to animate a certain UIView by using the translation transform from left to right. In order to do that though, I need to move the UIViews around programmatically, which I'm currently unable to do. The below is what I'm trying to essentially do (but it does not work because of autolayout):

_loginTextLabel.center = CGPointMake(1,1);

[UIView animateWithDuration:0.5 delay:0.5 options:nil animations:^{
    _loginTextLabel.center= CGPointMake(5, 1);

} completion:nil
 ];
}
Vimzy
  • 1,871
  • 8
  • 30
  • 56
  • There are a couple of interesting ideas in this post: http://stackoverflow.com/questions/11368440/can-i-disable-autolayout-for-a-specific-subview-at-runtime A simple place to start, try setting `translatesAutoresizingMaskIntoConstraints = YES` before setting the new center. – William Smith Sep 07 '15 at 01:39
  • @WilliamSmith One additional problem. Why does "CGPointMake(_loginTextLabel.bounds.origin.x, _loginTextLabel.bounds.origin.y)" produce a (0,0) value when I use it? It's wrong. Is this also an autolayout problem? – Vimzy Sep 07 '15 at 02:49
  • I guess first I will ask, why do you think its wrong? The bounds property defines the drawable area of the UIView relative to the frame. It usually defaults to (0, 0, width, height). From the Apple docs "The size of the bounds rectangle is coupled to the size of the frame rectangle, so that changes to one affect the other. Changing the bounds size grows or shrinks the view relative to its center point." You can read up on the bounds property here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instp/UIView/bounds – William Smith Sep 07 '15 at 02:59

2 Answers2

1

Actually you can layout your _loginTextLabel in - (void)viewDidLayoutSubviews (or - (void)layoutSubviews if it is in your custom view) without autolayout, then you can animate your view like you did before without any bother.

If you layout your views using autolayout from a Nib, then you can create a outlets of your constraint as Abhishek says,basically like this:

[self.view layoutIfNeeded];
yourConstraint.constant = whateverYouWant;
[UIView animateWithDuration:1.0 animations:^{ 
   [containerView layoutIfNeeded]; }
];

Or if you create your constraints programmatically,as apple suggested:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutolayoutPG.pdf

it's basically like you did from a Nib, difference is that you just make your constraints changes in the animation block

[containerView layoutIfNeeded]; 
[UIView animateWithDuration:1.0 animations:^{
// Make all constraint changes here
[containerView layoutIfNeeded]; // Forces the layout of the subtree animation
block and then captures all of the frame changes
}];
John
  • 525
  • 3
  • 14
  • 1
    Can you explain how I'm actually supposed to use this line: "yourConstraint.constant = whateverYouWant;" and what it's for? – Vimzy Sep 07 '15 at 08:05
  • @Vimzy Say you got a button, and you create a outlet of its leading constraint to its superview, with a fixed value like 10,something like this:@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingConstraint; When you move your button horizontally, you can change your constraint's value from 10 to any other value you want, so just give it a new value,like: self.leadingConstraint.constant = 100; – John Sep 07 '15 at 08:35
0

In order to handle Autolayouts programmatically, you need to create the IBOutlets of your Constraint,they are of class NSLayoutConstraints, and where you want to change the position or frame you need to call updateConstraintsIfNeeded on your view.Then you need to set a float value to the Constant property of your outlet.

_constraintHeight.constant = 200;