当我使用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];
}