你能在Swift中创建匿名内部类吗?

时间:2014-08-11 15:43:47

标签: ios swift uialertview anonymous-inner-class uialertviewdelegate

我已经厌倦了宣布整个课程能够通过延长UIAlertView来处理UIAlertViewDelegate次点击。当我有多个可能的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) {
        // ...
    }
}

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

2 个答案:

答案 0 :(得分: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"
        )
    }
}

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

答案 1 :(得分:1)

不幸的是,据我所知,没有你不能有效地创建匿名内部类。你建议的语法虽然非常好,但是。

这是我尝试接近你想要的东西,虽然不是那么干净。

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")
    }

}
相关问题