简体   繁体   English

动画重新放置其他视图后,从其超级视图中删除视图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM