我该如何在Swift中创建一个UIAlertView?

555

我一直在努力使用Swift创建UIAlertView,但由于某种原因,我无法正确编写语句,因为我得到了这个错误:

找不到接受提供的参数的“init”重载

以下是我的编写方式:

let button2Alert: UIAlertView = UIAlertView(title: "Title", message: "message",
                     delegate: self, cancelButtonTitle: "OK", otherButtonTitles: nil)

然后我使用以下代码进行调用:

button2Alert.show()

截至目前它正在崩溃,我似乎无法正确地编写语法。


6
iOS 8中已经用UIAlertController替代了UIAlertView和UIActionSheet,你有看过吗?请注意不要改变原意。 - Popeye
请确保self所属的类采用了协议UIAlertViewDelegate(在Swift中,推荐的方法是使用扩展)。 - Nicolas Miari
@Adam:我已经恢复了您的重新标记。[tag:swift3]标签用于与苹果Swift编程语言第三版中的更改直接相关的问题。我认为来自https://meta.stackoverflow.com/questions/252079/tagging-a-question-based-on-its-answers的“If the answers make it clear that the problem in the question was caused by something other than what the asker thought, retagging is very helpful.”并不适用于这里。 - Martin R
1
@MartinR 我不知道如何更新问题以显示有适用于当前版本的Swift的答案;这里有很多旧的、无用的东西,[swift]与有用的东西一起找到了它们。我对这个重新标记被还原并没有强烈的感觉,但我希望有一个明确的方法来解决这个问题。(我希望答案有标签。) - Adam Eberbach
36个回答

10

AlertView Swift 5 及以上版本:

let alert = UIAlertController(title: LocalizedStringConstant.alert, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Retry", style: .cancel, handler: { (_) in
     }))
self.present(alert, animated: true, completion: nil)

9

我找到了这个,

var alertView = UIAlertView();
alertView.addButtonWithTitle("Ok");
alertView.title = "title";
alertView.message = "message";
alertView.show();

虽然不太好,但它能用 :)

更新:

但我在头文件中找到了如下内容:

extension UIAlertView {
    convenience init(title: String, message: String, delegate: UIAlertViewDelegate?, cancelButtonTitle: String?, otherButtonTitles firstButtonTitle: String, _ moreButtonTitles: String...)
}

有人可以解释这个吗?

显然UIAlertView在iOS 8中已被弃用,我们现在使用UIAlertController,并且首选样式为UIAlertControllerStyleAlert。 - BlueBear
6
如果您运行的应用程序需要向后兼容到iOS7.1,并且您正在使用Swift编写它,那么UIAlertController会导致目标设备崩溃。您需要支持iOS7的传统UIAlertViews。 - Joe
我认为导致崩溃的不是Swift语言,而是UIAlertController在iOS 8之前不可用的事实。 - Frederic Adda

7

针对 iOS 13 Xcode 11+ Swift 5.X

UIAlertController 现在可以提供警告和操作表

警告

// First instantiate the UIAlertController

let alert = UIAlertController(title: "Title",
                              message: "Message ?",
                              preferredStyle: .alert)


 // Add action buttons to it and attach handler functions if you want to 

 alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
 alert.addAction(UIAlertAction(title: "Just Do It!", style: .destructive, handler: nil))
 alert.addAction(UIAlertAction(title: "Maybe", style: .default, handler: nil))

// Show the alert by presenting it

self.present(alert, animated: true)

请注意,当点击操作按钮时,关闭警告视图是所有操作按钮的基本特性。其中style参数仅用于决定文本的颜色(以及一些默认顺序,按钮的顺序可以更改)。
示例处理程序函数可能如下:
func handler(_ action: UIAlertAction) { 

   if action.title == 'Title' {
       // do stuff
   }

}

作为一个旁注,我认为你可以只创建一个处理程序,并按照上述方式追溯触发它的元素。
我们也可以检查alert.style,但这样我们就可以有多个默认样式的操作,我不建议这样做。 操作表 解释类似,因为主要区别在于警报会打断用户,而操作表会从底部滑动到 iPhone 上,在 iPad 上则呈现为弹出视图
操作表的目的是根据用户当前状态指导用户决定其操作。所以你必须像处理十字路口一样对待操作表!通常没有消息,标题呈现为字幕大小的文本。
let action = UIAlertController(title: "What do you want to do with the message",
                               message: nil,
                               preferredStyle: .actionSheet)

action.addAction(UIAlertAction(title: "Cancel", style: .cancel)) 

for act in ["Save", "Post", "Discard"] {  
          action.addAction(UIAlertAction(title: act, style: .default, handler: nil))
}

self.present(action, animated: true)

上面的代码在iPhone上可以工作,但是在iPad上会在运行时崩溃,因为UIPopoverPresentationController将负责警告,并且此时它不会引用任何内容。因此,为了避免这种情况,您必须提供以下必要的代码块。
if let pop = action.popoverPresentationController {

     let v = sender as! UIView 
     pop.sourceView = v 
     pop.sourceRect = v.bounds
 }

同样,对于iPad而言,在弹出窗口之外的任何地方轻触都会使其消失,并调用“取消”操作按钮的完成处理程序。
希望这有所帮助 :) 话虽如此,如果您有任何疑问,请在下方评论。

在视图控制器的上下文中,Self指代当前实例化的视图控制器对象。 - Tilak Madichetti

5
我已经创建了一个单例类,使得在应用程序的任何地方都能方便地使用它:https://github.com/Swinny1989/Swift-Popups 您可以像这样创建一个带有多个按钮的弹出窗口:
Popups.SharedInstance.ShowAlert(self, title: "Title goes here", message: "Messages goes here", buttons: ["button one" , "button two"]) { (buttonPressed) -> Void in
    if buttonPressed == "button one" { 
      //Code here
    } else if buttonPressed == "button two" {
        // Code here
    }
}

或者像这样只有一个按钮的弹出窗口:

Popups.SharedInstance.ShowPopup("Title goes here", message: "Message goes here.")

谢谢。我在那里提交了一些问题。 - djdance
1
嘿@Swinny89,非常感谢你与我们分享这个解决方案!我被闭包卡住了,你救了我! - Bruno Campos

5
    class Preview: UIViewController , UIAlertViewDelegate
    {
        @IBAction func MoreBtnClicked(sender: AnyObject)
        {
            var moreAlert=UIAlertView(title: "Photo", message: "", delegate: self, cancelButtonTitle: "No Thanks!", otherButtonTitles: "Save Image", "Email", "Facebook", "Whatsapp" )
            moreAlert.show()
            moreAlert.tag=111;
        }

        func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int)
        {
            if alertView.tag==111
            {
                if buttonIndex==0
                {
                    println("No Thanks!")
                }
                else if buttonIndex==1
                {
                    println("Save Image")
                }
                else if buttonIndex == 2
                {
                    println("Email")
                }
                else if buttonIndex == 3
                {
                    println("Facebook")
                }
                else if buttonIndex == 4
                {
                    println("Whatsapp")
                }
            }
        }
    }

仅仅写一大堆代码是没有多大用处的。当回答任何问题(特别是一个包含多个答案,其中包括一个被接受的答案的旧问题)时,请不要只写一段代码。请添加对您的代码所做的解释,它如何回答问题以及它与其他答案的区别(或优劣之处)。 - AdrianHHH

5

Swift 3

以下是使用 Swift 3 创建一个简单的带有一个按钮的警告框的示例。

let alert = UIAlertController(title: "Title",
                              message: "Message",
                              preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default))
present(alert, animated: true)

在上面的例子中,省略了操作的句柄回调,因为带有一个按钮的警报视图的默认行为是在点击按钮时消失。
以下是如何创建另一个操作,该操作可以添加到使用"alert.addAction(action)"添加的警报中。不同的样式有.default、.destructive和.cancel。
let action = UIAlertAction(title: "Ok", style: .default) { action in
    // Handle when button is clicked    
}

5

我有一个小技巧。假设您有5个类需要应用注销警报。可以尝试使用Swift类扩展。

文件- 新建- Swift类- 命名。

添加以下内容:

public extension UIViewController
{

    func makeLogOutAlert()
    {
        var refreshAlert = UIAlertController(title: "Log Out", message: "Are You Sure to Log Out ? ", preferredStyle: UIAlertControllerStyle.Alert)

        refreshAlert.addAction(UIAlertAction(title: "Confirm", style: .Default, handler: { (action: UIAlertAction!) in
            self.navigationController?.popToRootViewControllerAnimated(true)
        }))

        refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action: UIAlertAction!) in
            refreshAlert .dismissViewControllerAnimated(true, completion: nil)
        }))

        presentViewController(refreshAlert, animated: true, completion: nil)
    }
}

使用以下代码实现: self.makeLogOutAlert()。希望这能有所帮助。

4
 let alertController = UIAlertController(title: "Select Photo", message: "Select atleast one photo", preferredStyle: .alert)
    let action1 = UIAlertAction(title: "From Photo", style: .default) { (action) in
        print("Default is pressed.....")
    }
    let action2 = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
        print("Cancel is pressed......")
    }
    let action3 = UIAlertAction(title: "Click new", style: .default) { (action) in
        print("Destructive is pressed....")

    }
    alertController.addAction(action1)
    alertController.addAction(action2)
    alertController.addAction(action3)
    self.present(alertController, animated: true, completion: nil)

}

4

我已经成功编译以下UIAlertView初始化代码(我认为最后的可变部分可能有些棘手)。但是,我必须确保self的类(我将其作为委托传递)正在采用UIAlertViewDelegate协议,以使编译错误消失:

let alertView = UIAlertView(
                  title: "My Title",
                  message: "My Message",
                  delegate: self,
                  cancelButtonTitle: "Cancel",
                  otherButtonTitles: "OK"
                )

顺便提一句,以下是我收到的错误消息(截至Xcode 6.4):
无法找到类型为“UIAlertView”的初始化器,该初始化器接受类型为“(title: String, message: String, delegate: MyViewController, cancelButtonTitle: String, otherButtonTitles: String)”的参数列表。
正如其他人所提到的,如果您可以针对iOS 8.x+进行目标设置,则应迁移到UIAlertController。要支持iOS 7,请使用上面的代码(iOS 6不支持Swift)。

4

或者只需这样做

        let alert = UIAlertController(title: "Alert", message: "Saved Successfully", preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
        self.present(alert, animated: true, completion: nil)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接