[英]Removing a view from it's superview after animation repositions other views
My app simulates a playing card game. 我的应用程序模拟了纸牌游戏。 I have a view called
gridView
in my controller, which contains 16 card views. 我的控制器中有一个名为
gridView
的视图,其中包含16个卡视图。 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
. 我使用两个数组:
cardViews
包含网格视图内的所有卡片视图,但不包含那些需要通过动画删除的卡片视图,它们包含在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. PS:如果我不打电话给
[view removeFromSuperview]
行,请修复所有问题,但我需要将其从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: 如果我使用autolayout,xcode似乎想自动将约束添加到未指定约束的视图中:
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. 我找到的解决方案是子类化
UIView
并重写addConstraint:
和addConstraints:
而无需调用超类实现,从而不会真正添加约束。 This works perfectly without any crash. 这完美地工作而不会崩溃。
- (void) addConstraint:(NSLayoutConstraint *)constraint {
}
- (void) addConstraints:(NSArray *)constraints {
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.