iPhone中真正的模态UIAlertView?

Posted

技术标签:

【中文标题】iPhone中真正的模态UIAlertView?【英文标题】:Truly modal UIAlertView in iPhone? 【发布时间】:2009-02-21 21:22:17 【问题描述】:

我需要根据用户的决定运行一些验证(例如,如果批准超过支出限额的购买),如果失败则拒绝“完成”操作。

但是,看起来不可能像其他语言(如 showmessage、alert() 等)那样具有真正的模态操作,并且一切都由代表完成。

但是我不知道该怎么办。如果用户按下“完成”按钮,程序会询问“你确定吗?”他说“取消”流程继续,视图被推回!

可可世界如何解决这个问题?

【问题讨论】:

【参考方案1】:

解决方案是不要与之抗争,只需将您的逻辑分成两部分。如果用户单击取消,则不执行第二部分。如果用户点击确定/继续,则执行第二部分。

阻塞主线程导致的主要问题是主线程是处理事件的。处理事件的经典方式可能会引入奇怪的事件处理错误,因为您没有一个事件循环,而是将多个事件循环嵌入到另一个事件循环中。

通过使用委托,您可以利用一个事件循环(通过 UIApplicationMain 调用),而不会出现任何这些事件处理异常。

【讨论】:

换句话说,彻底重组你的代码,并祈祷在你计划发布的前一天你不会让你的用户在一个大的中间要求验证,用一堆局部变量进行复杂的计算。【参考方案2】:

查看: http://code.google.com/p/modal-uialertview-uiactionsheet/

使用它,您可以执行以下操作:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil];
if ([actionSheet showModalInView:self.view] == actionSheet.destructiveButtonIndex) 
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Do you want to delete this file?" delegate:nil cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil];
    if ([alertView showModal]!= alertView.cancelButtonIndex) 
        // Delete the file
    

【讨论】:

这比私有方法 [alert setRunsModal:YES] 效果更好,因为在 Apple 的实现中,当您显示第二个警报时,第一个警报会被取消。但是,通过此实现,您可以拥有嵌套警报。【参考方案3】:

将应用程序的状态保存在函数中的变量以外的其他位置。例如,在我的一个应用程序中,有一个配置文件字符串说明他们是否同意隐私政策。

【讨论】:

【参考方案4】:

我刚刚以 MonoTouch 问题的形式遇到了这个问题,并且在研究解决方案时遇到了这个未解决的问题。

简短的回答是,是的,这是可能的。以下示例展示了如何在 iPhone 上使用 MonoTouch 和 C# 完成此操作,但同样的原理也适用于 Objective-C。

为此,您可以手动运行主循环。我没有设法直接停止主循环,所以我改为运行主循环 0.5 秒并等待用户响应。

以下函数显示了如何使用上述方法实现模态查询:

int WaitForClick ()

    int clicked = -1;
    var x = new UIAlertView ("Title", "Message",  null, "Cancel", "OK", "Perhaps");
    x.Show ();
    bool done = false;
    x.Clicked += (sender, buttonArgs) => 
        Console.WriteLine ("User clicked on 0", buttonArgs.ButtonIndex);
    clicked = buttonArgs.ButtonIndex;
    ;    
    while (clicked == -1)
        NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
        Console.WriteLine ("Waiting for another 0.5 seconds");
    

    Console.WriteLine ("The user clicked 0", clicked);
    return clicked;

【讨论】:

【参考方案5】:

我同意 NilObject 的观点,即您通常不应该与之抗争,而且我通常不会。但是我使用的是 AddressBookUI 框架,当我在委托方法中时,

- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier

我真的很想警告用户,例如,当他们单击地址时,他们将离开应用程序,这会触发地图应用程序。我使用 MapKit 制作自己的地图,但我没有耐心重现完整的地图应用程序(让用户从其他地址获取路线),只好让 shouldPerformDefaultAction 完成它的工作和启动地图应用程序,但我无法警告用户他们将离开应用程序。

我真的希望 Apple 提供一个非常基本的模型 UIAlertView 而不是绕开它。这很愚蠢。

【讨论】:

以上是关于iPhone中真正的模态UIAlertView?的主要内容,如果未能解决你的问题,请参考以下文章

ios 8 应用程序扩展以显示 UIAlertView 之类的视图而不是模态 UIViewController?

如何在 iPhone 的 UIAlertView 中添加 UITableView?

如何在 iPhone 应用程序的不同文件中为 UIAlertview 设置委托

如何在 UIAlertView iPhone 中添加 TextView 320*460

自定义 UIAlertView iphone

iPhone App 中的 UIAlertView 动态