My app simulates a playing card game. I have a view called gridView
in my controller, which contains 16 card views. The card views are already positioned inside the grid view (it's the green one) without any layout constraint:
Now in some moment of the game I need to animate two card views, displacing them outside the screen bounds, and after the animation is completed, I need to remove them from it's superview (the grid view). But I need to do this not simultaneously, but one view per time, so I use an animation that when finishes it triggers the other one.
I use two arrays: cardViews
contains all the card views inside the grid view, but not the ones that need to be removed with an animation, those are contained in matchedCardViews
. So I've written this method:
- (void) animateMatchedCardViews {
if(self.matchedCardViews.count) {
UIView* view= self.matchedCardViews.firstObject;
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
view.frame= aFrameOutOfScreenBounds; // I checked out: the frame is computed
// correctly, converted in grid view's
// coordinates
} completion:^(BOOL finished) {
[view removeFromSuperview];
[self.matchedCardViews removeObject:view];
// I recursively call the method to remove the other card
// in self.matchedCardViews.
[self animateMatchedCardViews];
}];
}
}
But removing the view from it's superview messes up everything: the first animation goes well and I see the view slowly going out of the screen, but the second animation is totally wrong: all other views I don't know why are layout'd again, in wrong positions, and the second card view that should animate moves not to a point outside the screen, but inside the grid view. The view in a red circle is the one that moved to a wrong position:
PS: If I don't call the line [view removeFromSuperview]
all fixes, but I need to remove it from the superview.
Try this,
- (void) animateMatchedCardViews {
if(self.matchedCardViews.count) {
UIView* view= self.matchedCardViews.firstObject;
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
view.frame= aFrameOutOfScreenBounds; // I checked out: the frame is computed
// correctly, converted in grid view's
// coordinates
} completion:^(BOOL finished) {
if (finished) {
[view removeFromSuperview];
[self.matchedCardViews removeObject:view];
// I recursively call the method to remove the other card
// in self.matchedCardViews.
[self animateMatchedCardViews];
}
}];
}
}
It seems like xcode wants to automatically add constraints to views for which no constraint is specified, if I use autolayout:
Probably it does so to resolve the ambiguity, but in my case there isn't any ambiguity because I manually position the views inside the grid view.
The solution I've found is to subclass UIView
and to override addConstraint:
and addConstraints:
, without calling the superclass implementation so that the constraints aren't really added. This works perfectly without any crash.
- (void) addConstraint:(NSLayoutConstraint *)constraint {
}
- (void) addConstraints:(NSArray *)constraints {
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.