patternMinor
Loop Animation on several UIButton's NSLayoutConstraint
Viewed 0 times
nslayoutconstraintanimationloopuibuttonseveral
Problem
I took the belated plunge to look at Autolayout. Normally I'd animate based on a UIView's frame (i.e I'd have used the following):
Am I right in thinking that I now have to animate based on the
The end result I get is what I desire, but something doesn't seem right.
NSArray *sortedArray = [self.buttonArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:ascendingSort]];
for (int i = 0;i<sortedArray.count;i++) {
UIButton * theButton = [sortedArray objectAtIndex:i];
[UIView animateWithDuration:1 delay:i *0.05 usingSpringWithDamping:10 initialSpringVelocity:20 options:UIViewAnimationOptionCurveEaseIn animations:^{
[theButton setFrame:frameToAnimateTo];
} completion:nil];
}Am I right in thinking that I now have to animate based on the
Constant property of a buttons constraint?NSArray *sortedArray = [self.ButtonHorizonalConstraints sortedArrayUsingDescriptors:[NSArray arrayWithObject:ascendingSort]];
for (int i = 0;i<sortedArray.count;i++) {
NSLayoutConstraint * constraint = [sortedArray objectAtIndex:i];
UIButton * theButton = constraint.firstItem;
constraint.constant = toShow?0:-theButton.frame.size.width;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:1 delay:i *(toShow?0.1:0.05) usingSpringWithDamping:10 initialSpringVelocity:toShow?20:-20 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}The end result I get is what I desire, but something doesn't seem right.
Solution
I'm not completely familiar with animating auto-layout constraints. Fortunately (or unfortunately), I've not yet ever had the need to do this. So, I'm not sure if there's a better way, but I'd say if it's working, that's a good sign.
What I do want to comment on is your readability:
I don't mind ternary operators. But I think you really need to include some white space. When it's all smushed together, and including the negative sign, I had to do a double take before I realized what's going on.
options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.view layoutIfNeeded];
} completion:nil];
This method call suffers the same problems as before with the smushed ternary operator, except it's worse because this method has so many more arguments and you're calculating so much in line and you're not using any vertical space.
I'd rewrite this as such:
With that spacing, even if we kept the ternaries in-line, it's still significantly more readable with a single argument per line.
What I do want to comment on is your readability:
constraint.constant = toShow?0:-theButton.frame.size.width;
[self.view setNeedsUpdateConstraints];I don't mind ternary operators. But I think you really need to include some white space. When it's all smushed together, and including the negative sign, I had to do a double take before I realized what's going on.
constraint.constant = toShow ? 0 : -theButton.frame.size.width;[UIView animateWithDuration:1 delay:i *(toShow?0.1:0.05) usingSpringWithDamping:10 initialSpringVelocity:toShow?20:-20options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.view layoutIfNeeded];
} completion:nil];
This method call suffers the same problems as before with the smushed ternary operator, except it's worse because this method has so many more arguments and you're calculating so much in line and you're not using any vertical space.
I'd rewrite this as such:
CGFloat animationDelay = i * (toShow ? 0.1 : 0.05);
CGFloat springVelocity = toShow ? 20 : -20;
[UIView animateWithDuration:1
delay:animationDelay
usingSpringWithDamping:10
initialSpringVelocity:springVelocity
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[self.view layoutIfNeeded];
} completion:nil];With that spacing, even if we kept the ternaries in-line, it's still significantly more readable with a single argument per line.
Code Snippets
constraint.constant = toShow?0:-theButton.frame.size.width;
[self.view setNeedsUpdateConstraints];constraint.constant = toShow ? 0 : -theButton.frame.size.width;[UIView animateWithDuration:1 delay:i *(toShow?0.1:0.05) usingSpringWithDamping:10 initialSpringVelocity:toShow?20:-20CGFloat animationDelay = i * (toShow ? 0.1 : 0.05);
CGFloat springVelocity = toShow ? 20 : -20;
[UIView animateWithDuration:1
delay:animationDelay
usingSpringWithDamping:10
initialSpringVelocity:springVelocity
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[self.view layoutIfNeeded];
} completion:nil];Context
StackExchange Code Review Q#61430, answer score: 3
Revisions (0)
No revisions yet.