10

我厌倦了将整个类声明为能够UIAlertView通过使它们扩展来处理点击UIAlertViewDelegate。当我有多个可能的 s 时,它开始感到混乱和错误UIAlertView,并且必须区分在处理程序中单击了哪个。

我真正想要的是创建一个实现UIAlertViewDelegate协议的对象,并在显示时将这个一次性对象提供给我UIAlertView

我想要这样的东西:

let confirmDelegate = UIAlertViewDelegate() {
    func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) {
        // Handle the click for my alertView
    }
}

然后在显示警报时使用它:

let alertView = UIAlertView(title: "Confirm", message: "Are you sure?", delegate: confirmDelegate, cancelButtonTitle: "No", otherButtonTitles: "Yes")
alertView.show()

在不声明新类的情况下这可能吗?

我知道我可以这样做:

class ConfirmDelegate: UIAlertViewDelegate {
    func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) {
        // ...
    }
}

然后实例化 a ConfirmDelegate(),但我只是想知道这是否可以作为单行类声明和实例化。

4

2 回答 2

7

正如@ChrisWagner 在他的评论中所说,你不应该在 iOS8 中做任何这些,至少UIAlertView因为有一个新UIAlertViewController的使用没有任何委托的闭包。但从学术的角度来看,这种模式还是很有趣的。

我根本不会使用匿名类。我只想创建一个可以分配为委托的类,并在发生某些事情时接受闭包来执行。

您甚至可以将其升级为接受每种操作的闭包:onDismissonCancel等。或者您甚至可以使此类生成警报视图,将其自身设置为委托。

import UIKit

class AlertViewHandler: NSObject, UIAlertViewDelegate {
    typealias ButtonCallback = (buttonIndex: Int)->()
    var onClick: ButtonCallback?

    init(onClick: ButtonCallback?) {
        super.init()
        self.onClick = onClick
    }

    func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) {
        onClick?(buttonIndex: buttonIndex)
    }
}


class ViewController: UIViewController {

    // apparently, UIAlertView does NOT retain it's delegate.
    // So we have to keep it around with this instance var
    // It'll be nice when all of UIKit is properly Swift-ified :(
    var alertHandler: AlertViewHandler?

    func doSoemthing() {
        alertHandler = AlertViewHandler({ (clickedIndex: Int) in
            println("clicked button \(clickedIndex)")
        })

        let alertView = UIAlertView(
            title: "Test",
            message: "OK",
            delegate: alertHandler!,
            cancelButtonTitle: "Cancel"
        )
    }
}

传递闭包应该可以减轻对匿名类的需求。至少对于最常见的情况。

于 2014-08-11T18:02:06.483 回答
1

不幸的是,据我了解,不,您不能有效地创建匿名内部类。不过,您建议的语法将是非常好的 IMO。

这是我试图获得接近你想要的东西的尝试,但它远没有那么干净。

import UIKit

class AlertViewDelegate: NSObject, UIAlertViewDelegate {
    func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) {

    }

    func alertView(alertView: UIAlertView!, didDismissWithButtonIndex buttonIndex: Int) {

    }

    func alertView(alertView: UIAlertView!, willDismissWithButtonIndex buttonIndex: Int) {

    }

    func alertViewCancel(alertView: UIAlertView!) {

    }

    func alertViewShouldEnableFirstOtherButton(alertView: UIAlertView!) -> Bool {
        return true
    }
}


class ViewController: UIViewController {
    var confirmDelegate: AlertViewDelegate?

    func doSoemthing() {
        confirmDelegate = {

            class ConfirmDelegate: AlertViewDelegate {
                override func alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) {
                    println("clicked button \(buttonIndex)")
                }
            }

            return ConfirmDelegate()
        }()

        let alertView = UIAlertView(title: "Test", message: "OK", delegate: confirmDelegate, cancelButtonTitle: "Cancel")
    }

}
于 2014-08-11T17:18:12.347 回答