attempt to dismiss modal view controller

解决UIAlertView关闭动画导致的问题
本文介绍了一个UIAlertView在iOS应用中未完成关闭动画即切换视图控制器所导致的问题及解决方案。作者通过使用alertView的代理方法,在alertView完全关闭后进行视图控制器的切换,从而避免了错误的发生。

问题描述

项目中,点击“退出登录”按钮,弹出alertView提示用户“确定退出登录吗?”,点击alertView上的确定按钮后,设置keyWindow为LoginController。

代码如下:

- (void)logOut {
	UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"确定要退出吗?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
	[alertView show];
}

#pragma mark alertView代理方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
	if (buttonIndex == 1) {
        //跳转到登录界面
        LoginController *loginVC = [[LoginController alloc] init];
        [UIApplication sharedApplication].keyWindow.rootViewController = loginNewVC;
	}
}

运行过后,Xcode给出如下警告:

attempt to dismiss modal view controller whose view does not currently appear. self = <_UIModalItemAppViewController: 0x15f5fb10> modalViewController = <_UIModalItemsPresentingViewController: 0x15f62ab0>

问题解决

通过分析,问题应该是出在alertView还未完全dismiss掉就马上切换了根视图控制器。(alertView默认dismiss时带动画效果,需要消耗一定时间)。

所以,这里使用alertView的另一个代理方法解决问题,这个方法在alertView完全dismiss掉后调用,如下:

//This method is invoked after the animation ends and the view is hidden.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex


在使用 `a-modal` 组件(来自 Ant Design Vue)时,如果控制台出现错误提示 `Invalid attempt to destructur`,通常与解构赋值相关。这种错误往往发生在尝试对一个未定义(`undefined`)或非对象类型的变量进行解构操作。 例如,在组件的 `props`、`data` 或某些方法中可能存在如下代码: ```javascript const { visible, row } = this; ``` 如果 `this` 上下文中的 `visible` 或 `row` 未正确初始化,或者在组件挂载前被访问,就可能导致此错误[^1]。 结合提供的引用内容来看,用户可能在父组件中通过 `props` 向子组件传递了如 `row` 等数据,但该数据在子组件内部被解构使用之前未被正确初始化[^2]。 ### 常见原因 1. **未正确初始化 props** 如果 `row` 是从父组件传入的 `prop`,但在父组件中未传递或传递为 `undefined`,则在子组件中对其解构会导致错误。 2. **异步数据加载问题** 如果 `row` 是通过异步请求获取的数据,并且在数据返回前就被解构使用,也会导致该错误。 3. **拼写错误或作用域问题** 在某些情况下,由于拼写错误或作用域链的问题,导致访问了错误的变量名或未绑定上下文。 --- ### 解决方案 #### 1. 设置默认值以避免解构失败 在子组件中接收 `props` 时,可以为其设置默认值,防止其为 `undefined`: ```javascript props: { row: { type: Object, default: () => ({}) } } ``` 这样即使父组件未传入 `row`,也能保证它是一个对象,从而支持安全解构。 #### 2. 使用可选链操作符(Optional Chaining) 在访问嵌套属性时,使用可选链 `?.` 可以有效防止运行时错误: ```javascript const value = this.row?.id; ``` #### 3. 检查生命周期钩子中的访问时机 确保在 `mounted` 生命周期钩子之后再访问依赖于 DOM 或异步数据的变量,而不是在 `created` 中过早访问。 #### 4. 验证事件传递逻辑 如果 `a-modal` 内部涉及事件通信(如点击确认按钮后触发的方法),请检查事件处理函数是否正确绑定了 `this` 上下文,或使用箭头函数来保留作用域: ```javascript methods: { confirmHandler: () => { const { name, address } = this.formValidate; // 处理逻辑 } } ``` --- ### 示例修复代码 假设在 `a-modal` 子组件中有如下逻辑: ```javascript mounted() { const { id, name } = this.row; // 若 row 为 undefined 则报错 } ``` 应改为: ```javascript props: { row: { type: Object, default: () => ({}) } }, mounted() { const { id = null, name = '' } = this.row || {}; // 安全解构 } ``` --- ### 总结 `Invalid attempt to destructur` 错误本质是 JavaScript 的解构语法要求操作对象必须为可迭代类型(如对象、数组)。因此,在使用 `a-modal` 或其他组件时,务必确保所有被解构的变量都已正确初始化,尤其是在组件通信和异步数据加载场景中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值