I came across a weird scenario, that I just can't figure out on my own.
I started a little test scenario, with an almost empty iOS Single View Application and a storyboard. The story boards contains a label and single UIView, 10x10, just for presenting the issue. Of course they have the appropriate IBOutlets assigned and connected:
@property (nonatomic, weak) IBOutlet UILabel *label;
@property (nonatomic, weak) IBOutlet UIView *dot;
In the (void)viewDidLoad method I start a timer and add it to the run loop like that:
- (void)viewDidLoad {
[super viewDidLoad];
NSTimer * timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(doSomething) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
In the (void)doSomething method I do the following:
-(void)doSomething {
// Lets move the dot to the right a bit further
_dot.center = CGPointMake(_dot.center.x+1, _dot.center.y);
// About every ten steps, update the label with the current
// X position, to better show the problem
CGFloat moduloResult = (float)((int)_dot.center.x % (int)10.0);
if(moduloResult <= 0)
_label.text = [NSString stringWithFormat:@"%f", _dot.center.x+1];
}
So basically, I change the center of the little 10x10 dot-view every time by 1, and every 10th time I update the label to show the current X position. For that matter it doesn't even matter with what I update the label text, it's just important that it changes. And I only change the text every 10 times to better show the problem here.
If I run that code the dot moves just as intended to the right, but then when I update the label text, the dot view gets reset and jumps back to it's original position. So updating my label text resets my other views on the Storyboard, which totally confuses me.
Can someone reproduce that or even explain it?
Thanks all, in advance :)
Alex
Answers
I was able to reproduce described behaviour, here is why it is happening:
By default, position of elements is determined by auto generated AutoLayout constraints
When changing position of
dot you are only updating it's current frame, not underlying constraintsChanging the text of
UILabel possibly changes size of UILabel's content, so it's frame needs to be recalculated. Here entire layout is recalculated based on constraints, thus also reseting frame of the dot.For resolving, I'd suggest to properly specify AutoLayout constraints and updating them instead of position directly.
Answers
That was pretty much it, the AutoLayout constraints pushed the view always back to it' original place, which kind of makes sense I guess, that's what the AutoLayout is supposed to do.
So, since I wanted my litte 10x10 dot-view to move around the screen (for practicing purposes, I changed my code. I try to explain it, lack of reputation just currently keeps me from posting the appropriate images.
I made two custom AutoLayout constraints, telling it to keep the view always 120px from the left of the superview and 100px from the top of the superview. I also specified the constraint for a fixed width and height of each 10. Since for a valid constraint you need the combination of x and y as well as height and width (at least as far as I understand it).
-
|
| Constraint *n* from top
|
|------|
Constraint | view |
*n* from left | _dot |
|--------------- |------|
Then I created two IBOutlets for the two Constraints:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *c1X;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *c1Y;
I changed my (void)doSomething method to this:
-(void)doSomething {
// Lets move the dot to the right a bit
// further by changing its Constraint
_c1X.constant++;
// About every ten steps, update the labe with the current
// X position, to better show the problem
CGFloat moduloResult = (float)((int)_dot.center.x % 10);
if(moduloResult <= 0)
_label.text = [NSString stringWithFormat:@"%f - %f - %f", _c1X.constant, _dot.center.x, _dot.center.y];
}
It works, the changing of the constraint instead of the actual view now moves the view over the screen. If this is best practice, I don't know. If I wouldn't have tried it for practice purposes, following a aged tutorial, I wouldn't come up with that in the first place.
In the hopes this might help one day. Any comments or improvements are welcome :)
Alex

