从SuperView的ViewController外部的类调用时,willRemoveSubview不会删除子视图吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从SuperView的ViewController外部的类调用时,willRemoveSubview不会删除子视图吗?相关的知识,希望对你有一定的参考价值。

当我使用Objective-C和UIView willRemoveSubview方法以编程方式删除子视图时,我不明白我在ios应用程序中观察到的不同行为。

方法1 在我的ViewController类中,我添加了一个UIVisualEffectView作为ViewController视图的子视图:

- (void)blurView {
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    blurEffectView.frame = self.view.bounds;
    blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.view insertSubview:blurEffectView atIndex:5];
}

响应用户的某些动作调用此方法。

blurEffectView本身是我在实现中定义的ViewController类的私有变量,它将指向新的子视图

@interface MyViewController ()

@end
@implementation
UIVisualEffectView *blurEffectView;  
...

我有一个Tap Gesture识别器,通过删除添加的子视图调用另一种方法“unblur”

- (void) tapped {
    blurEffectView.hidden = true;
    [self.view willRemoveSubview:blurEffectView];
}

此方法工作正常,模糊显示并覆盖视图。当点击发生时,模糊消失,一切看起来都不错。

方法2 接下来我尝试了一些更复杂的东西,现在它的行为有所不同。我创建了一个小的Objective-C类来将blur / unblur函数包装在一个单独的实用程序对象中,我可以更容易地重用它。

基本上MyViewController现在有一个新的私有变量来引用我的新类ViewBlurrer,它只扩展了NSObject。 ViewBlurrer现在封装了对UIVisualEffectView * blurEffectView的引用,它的界面有模糊和unblur的公共方法。 所以层次结构类似于MyViewController - > ViewBlurrer - > UIVisualEffectView

ViewBlurrer还维护对MyViewController.view的引用,它在blur和unblur方法中使用。调用此指针parentView。

这对于模糊来说表现完全相同,它正确地添加了覆盖ViewController视图的模糊效果。

我观察到的不同之处在于,我无法隐藏和删除现在它在此实用程序类ViewBlurrer中的blurEffectView。我可以删除的唯一方法是使用ViewBlurrer.unblur方法中的任意标记号查找UIVisualEffectView:

-(void)unblurView {
    UIView *theSubView = [self.parentView viewWithTag:66];
    theSubView.hidden = YES;
    [self.parentView willRemoveSubview:theSubView];
}

我的问题是为什么我不能只调用[self.parentView willRemoveSubview:blurEffectView],但我必须通过标签查找不是我插入到parentView的blurEffectView指针仍然等效于原始方法中的方法1?

答案

正如你在问题的评论中已经提到的那样,你不应该自己打电话给willRemoveSubview。从视图层次结构中删除子视图时,会自动调用(由系统)。从willRemoveSubview的文档:

当子视图接收到removeFromSuperview()消息或者从视图中删除子视图时,会调用此方法,因为它被添加到addSubview(_ :)的另一个视图中。

因此你应该写:

- (void) tapped {
    blurEffectView.hidden = true;
    [blurEffectView removeFromSuperview];
}

或更短:

- (void) tapped {
    [blurEffectView removeFromSuperview];
}

以上是关于从SuperView的ViewController外部的类调用时,willRemoveSubview不会删除子视图吗?的主要内容,如果未能解决你的问题,请参考以下文章

从它自己的 UView 子类中添加 UIView 作为 SuperView 子视图

如何将tableView的约束设置为viewController?

在 Superview 中更改子视图的框架

如何在 Superview 的视图中插入视图? (iOS)

Superview中UIPageControl的编程垂直对齐使用NSLayoutConstraint

自动布局约束不会设置为 SuperView 的边缘 [重复]