use*_*234 53 uiviewcontroller ios
假设我有一个名为VC2的视图控制器类的实例.在VC2中,有一个"取消"按钮会自动解除.但是当"取消"按钮被触发时,我无法检测或接收任何回调.VC2是一个黑盒子.
视图控制器(称为VC1)将使用presentViewController:animated:completion:方法呈现VC2 .
当VC2被解雇时,VC1必须检测哪些选项?
编辑:从@rory mckinnel的评论和@NicolasMiari的回答,我尝试了以下内容:
在VC2中:
-(void)cancelButton:(id)sender
{
[self dismissViewControllerAnimated:YES completion:^{
}];
// [super dismissViewControllerAnimated:YES completion:^{
//
// }];
}
Run Code Online (Sandbox Code Playgroud)
在VC1中:
//-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
- (void)dismissViewControllerAnimated:(BOOL)flag
completion:(void (^ _Nullable)(void))completion
{
NSLog(@"%s ", __PRETTY_FUNCTION__);
[super dismissViewControllerAnimated:flag completion:completion];
// [self dismissViewControllerAnimated:YES completion:^{
//
// }];
}
Run Code Online (Sandbox Code Playgroud)
但dismissViewControllerAnimatedVC1中没有被调用.
Ror*_*nel 44
根据文档,呈现控制器负责实际解雇.当呈现的控制器解散时,它会要求演示者为此进行操作.因此,如果你在VC1控制器中覆盖dismissViewControllerAnimated,我相信当你在VC2上点击取消时它会被调用.检测解雇,然后调用将执行实际解雇的超类版本.
从讨论中发现,这似乎不起作用.而不是依靠的不是调用底层机制,dismissViewControllerAnimated:completion在VC2本身,叫dismissViewControllerAnimated:completion上self.presentingViewController在VC2.然后,这将直接调用您的覆盖.
一个更好的方法是让VC2提供一个在模态控制器完成时调用的块.
所以在VC2中,提供一个带有名称的块属性onDoneBlock.
在VC1中,您提供如下:
在VC1中,创建VC2
将VC2的done处理程序设置为: VC2.onDoneBlock={[VC2 dismissViewControllerAnimated:YES completion:nil]};
使用[self presentViewController:VC2 animated:YES completion:nil]正常呈现VC2控制器;
在VC2中,在取消目标操作中调用 self.onDoneBlock();
结果是VC2告诉谁提出它已完成.你可以扩展onDoneBlock为有参数,表明模态是否被选中,取消,成功等....
Sen*_*ian 32
您可以在要观察另一个呈现的视图控制器的解除的父视图控制器UIViewControllerTransitioningDelegate上使用:
anotherViewControllerYouWantToObserve.transitioningDelegate = self
Run Code Online (Sandbox Code Playgroud)
并观察解雇情况:
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
print("anotherViewControllerYouWantToObserve was dismissed")
return nil
}
Run Code Online (Sandbox Code Playgroud)
bry*_*ejl 27
使用块属性
在VC2中声明
var onDoneBlock : ((Bool) -> Void)?
Run Code Online (Sandbox Code Playgroud)
在VC1中设置
VC2.onDoneBlock = { result in
// Do something
}
Run Code Online (Sandbox Code Playgroud)
当你即将解雇时,请在VC2中打电话
onDoneBlock!(true)
Run Code Online (Sandbox Code Playgroud)
Nic*_*ari 10
呈现和呈现的视图控制器都可以调用dismissViewController:animated:以便关闭呈现的视图控制器.
前一个选项(可以说)是"正确的",设计明智的:相同的"父"视图控制器负责呈现和解除模态("子")视图控制器.
但是,后者更方便:通常,"dismiss"按钮附加到呈现的视图控制器的视图,并且它将所述视图控制器设置为其动作目标.
如果您采用前一种方法,则您已经知道呈现视图控制器中发生解雇的代码行:在紧接着之后dismissViewControllerAnimated:completion:或在完成块之内运行代码.
如果您采用后一种方法(呈现的视图控制器自行解除),请记住,dismissViewControllerAnimated:completion:从呈现的视图控制器调用会导致UIKit在呈现视图控制器上调用该方法:
讨论
呈现视图控制器负责解除它所呈现的视图控制器.如果在呈现的视图控制器本身上调用此方法,UIKit会要求呈现视图控制器处理解雇.
因此,为了拦截此类事件,您可以在呈现视图控制器中覆盖该方法:
override func dismiss(animated flag: Bool,
completion: (() -> Void)?) {
super.dismiss(animated: flag, completion: completion)
// Your custom code here...
}
Run Code Online (Sandbox Code Playgroud)
extension Foo: UIAdaptivePresentationControllerDelegate {
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
//call whatever you want
}
}
vc.presentationController?.delegate = foo
Run Code Online (Sandbox Code Playgroud)
有一个特殊的布尔属性里面UIViewController叫isBeingDismissed,你可以使用这个目的:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isBeingDismissed {
// TODO: Do your stuff here.
}
}
Run Code Online (Sandbox Code Playgroud)
按以下方式使用willMove(toParent: UIViewController?)似乎对我有用。(在iOS12上测试)。
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent);
if parent == nil
{
// View controller is being removed.
// Perform onDismiss action
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有一个可以像页面一样通过滑动关闭的模态演示文稿,则此方法非常有效。
override func endAppearanceTransition() {
if isBeingDismissed{
print("dismissal logic here")
}
super.endAppearanceTransition()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
57425 次 |
| 最近记录: |