当我使用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视图的模糊效果。
我观察到的不同之处在于,我现在无法隐藏和删除blurEffectView,因为它在此实用程序类ViewBlurrer中。我可以删除的唯一方法是使用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中的原始方法吗?
答案 0 :(得分:1)
正如您在问题的评论中已经提到的那样,您不应该自己致电willRemoveSubview
。从视图层次结构中删除子视图时,会自动调用(由系统)。来自willRemoveSubview
的文档:
当子视图收到removeFromSuperview()消息或从视图中删除子视图时,会调用此方法,因为它已使用addSubview(_:)添加到另一个视图中。
因此你应该写:
- (void) tapped {
blurEffectView.hidden = true;
[blurEffectView removeFromSuperview];
}
或更短:
- (void) tapped {
[blurEffectView removeFromSuperview];
}