模态视图控制器出现在操作表后面
Posted
技术标签:
【中文标题】模态视图控制器出现在操作表后面【英文标题】:Modal View Controllers appear behind Action Sheet 【发布时间】:2010-12-15 18:15:48 【问题描述】:我的模式视图控制器显示在我的 UIActionSheet 后面,并且我的 UIActionSheet 没有被关闭。我正在使用:
[self presentModalViewController:composeTweetView animated:YES];
展示我的模态视图控制器。
我的操作表正在从 tabBar 显示:
[actionSheet showFromTabBar:self.parentViewController.tabBarController.tabBar];
此代码适用于 ios 4.0。
if (buttonIndex == 0)
if (self.isLoggedIn)
[FlurryAPI logEvent:@"ST_REPLY_CLICKED"];
composeTweetView.isDirectMessage = FALSE;
[self presentModalViewController:composeTweetView animated:YES];
[composeTweetView release];
else
LoginViewController* loginView = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
loginView.delegate = self;
loginView.isPostingComment = TRUE;
self.isReply = TRUE;
[self presentModalViewController:loginView animated:YES];
[loginView release];
[composeTweetView release];
总结:
我有一个包含 UITabBar 的 UIViewController。我正在展示一个 UIActionSheet,它有几个按钮来展示一个模态视图控制器。当模态视图控制器出现时,UIActionSheet 应该自行关闭,并且模态视图应该位于堆栈的顶部。问题是, UIActionSheet 没有关闭,并且在它后面加载了模态视图。这个问题直到 iOS 4.2.1 才出现
复制步骤:
-
创建一个TabBar项目,设置
你的基础 SDK 到 iOS 4.2.1
创建按钮或触发器以显示 UIActionSheet
允许 UIActionSheet 中的一个按钮使用以下语法呈现模式视图控制器:
[actionSheet showFromTabBar:self.parentViewController.tabBarController.tabBar];
预期结果:
1. The UIActionSheet should dismiss itself, and the modal view should appear in front
实际结果:
1. The UIActionSheet does not get dismissed and the modal view appears behind it.
回归:
This problem was not apparent prior to iOS 4.2.1
注意事项: 我尝试了其他显示 UIActionSheet 的方法,所有这些都无法按预期工作:
//[actionSheet showInView:self.parentViewController.tabBarController.tabBar];
//[actionSheet showInView:[self.view window]];
//[actionSheet showInView:self.parentViewController.tabBarController.view];
//[actionSheet showInView:[UIApplication sharedApplication].keyWindow];
【问题讨论】:
它在 4.2 中工作吗?实际上我在 4.2 中测试了该应用程序,它运行良好。 适用于 4.2。不适用于 4.2.1 你从哪里得到 4.2.1?在我的 DevCenter 中,最新的 XCode 来自 11 月 22 日,包含 4.2 而不是 4.2.1 还有一件事,随着 iOS SDK 的每个增量而损坏/脆弱。 【参考方案1】:为了重现您的问题,我整理了一个示例,查看了 UIActionSheet 委托方法。我相信你可以使用:
actionSheet:didDismissWithButtonIndex:
而不是
actionSheet:clickedButtonAtIndex:
我尚未对其进行测试,但我相信您仍然会得到相同的按钮编号,并且在操作表从视图中消失之前它不会触发。
【讨论】:
我使用的唯一委托方法是:-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
我需要手动关闭操作表吗?
仍然没有运气 :( 使用新的委托方法【参考方案2】:
抱歉,我不明白您的问题,但一切对我来说都很好。我在模拟器和 4.2.1 iPod Touch 4G 上尝试了以下代码(都有效)
- (IBAction)doit
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:@"title" delegate:self cancelButtonTitle:@"not OK" destructiveButtonTitle:@"Absolutely" otherButtonTitles:nil];
[actionSheet showFromTabBar:self.tabBarController.tabBar];
[actionSheet release];
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
if (buttonIndex == 0)
UIView *v = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];
[v release];
-
创建了 TabBar 示例项目
将按钮添加到 firstView-nib 并与相应的
IBAction
连接(必须将 FileOwner
命名为 FirstViewController
)
在FirstViewController.h
(<UIActionSheetDelegate>
)中设置委托方法
添加了上面的代码
//编辑:好的,我看到您想以模态方式呈现它,但即使这在 4.2.1 上也适用于我
TMPController *tmp = [[TMPController alloc]initWithNibName:@"TMP" bundle:nil];
[self presentModalViewController:tmp animated:YES];
[tmp release];
可能因为我用self.tabBarController.tabBar
所以可以,试试吧
【讨论】:
所以试试 self.tabBarController.tabBar 的东西 ;) [actionSheet showFromTabBar:self.parentViewController.tabBarController.tabBar]; //没有运气 hmm 真奇怪,你用的是什么设备?因为在我的 iPod Touch 4G iOS 4.2.1 (8C148) 上它按预期工作。尝试使用其他设备或其他 XCode 环境 我正在使用 iPhone 4 进行测试【参考方案3】:不确定您是否已经解决了这个问题。但我没有在上面看到明确的答案。我和你有完全一样的问题。所以最后,这是我这边的一个问题,但帮助我调试的是在方法中添加实际的操作代码
actionSheet:didDismissWithButtonIndex:
按照 Matthew 的建议。
这证明了这个观点实际上被驳回了。那时我意识到我将 UIActionSheet alloc 放在了 viewWillAppear 方法中。因此,每次视图出现时,它都会重新创建操作表。
【讨论】:
【参考方案4】:正如 SDK 文档所述,这看起来很奇怪:
actionSheet:clickedButtonAtIndex: … 调用此方法后,接收方会自动关闭。
我能想到它可能不会消失的 3 种可能性:
-
不调用处理动画和显示内容的主运行循环(主线程!)。您是否在主线程中处理过繁重的工作,例如同步网络调用? (注意 SDK 文本中的“之后”一词)
您计划以某种方式多次显示操作表
您以模态方式显示相同的视图控制器实例,该实例已经位于视图堆栈中当前视图下方的某个位置。
【讨论】:
我没有阻塞运行循环,一切都是异步的,动作表只被调用一次,与模态视图控制器一起,没有多个实例。奇怪的是,自从我在 iOS 3.0 上构建以来,这一直有效......【参考方案5】:我刚刚编写了一个快速示例应用程序来测试它,它的工作方式与我预期的一样(即,我无法重现您的问题)。 有点不同,因为我没有做 TabBar 应用程序,但我仍然希望这会有所帮助。我对UIActionSheet
所做的就是这样展示它:[actionSheet showInView:self.view]
。也许这会起作用?
抱歉,我的回答太仓促了,我正要出去的时候,这引起了我的注意。 :)
【讨论】:
[actionSheet showInView:self.view]
不幸地对我不起作用。相同的结果。奇怪的是我的代码如何在除 iOS 4.2.1 之外的所有版本上运行【参考方案6】:
我在 iOS 4.2 上也遇到过类似的问题。 我认为您应该尝试以下步骤:
-
为您希望在单击操作表按钮时执行的代码创建一个单独的方法。假设方法是 -(void)presentModalView
2.现在在-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex方法中,为被点击的对象调用presentModalView方法像这样的按钮索引:
if(buttonIndex==0)
[self performSelector:@selector(presentModalView) withObject:nil afterDelay:0.3];
3.您也可以尝试不同的延迟时间。
希望对你有帮助..
【讨论】:
运气不好。仍然显示在操作表后面,不会被关闭。 很抱歉..无法帮助您..但我还没有将我的 iOS 4.2 更新到 4.2.1。因此,无法重现该问题。【参考方案7】:我从 AlertBox/ActionSheet 调用 MailComposeView 时遇到了同样的问题,导致 MailCompseView 出现在不可见的屏幕后面。
我通过在 actionSheet 按钮处理程序中调用 dismissWithClickedButtonIndex:animated: 解决了这个问题。
【讨论】:
我在处理程序中尝试了 dismissWithClickedButtonIndex:animated: 但没有运气【参考方案8】:iOS5 已解决该问题。
【讨论】:
以上是关于模态视图控制器出现在操作表后面的主要内容,如果未能解决你的问题,请参考以下文章