Can you create anonymous inner classes in Swift?

一个人想着一个人 提交于 2019-12-05 01:47:32
Alex Wayne

As @ChrisWagner states in his comment, you shouldn't need to do any of this in iOS8, at least for UIAlertView since there is a new UIAlertViewController that uses closures without any delegates. But from an academic point of view, this pattern is still interesting.

I wouldn't use anonymous class at all. I would just create a class that can be assigned as the delegate and accept closures to execute when something happens.

You could even upgrade this to accept a closure for each kind of action: onDismiss, onCancel, etc. Or you could even make this class spawn the alert view, setting itself as the delegate.

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

Passing around closures should alleviate the need for anonymous classes. At least for the most common cases.

Unfortunately as far as I understand it, no you cannot effectively create anonymous inner classes. The syntax you suggest would be really nice IMO though.

Here is my attempt at getting something close to what you want, it's no where near as clean though.

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

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!