如何快速闭包引用它的类的运行的属性? [英] How can swift closure reference properties of class its running from?

查看:189
本文介绍了如何快速闭包引用它的类的运行的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下列出的2个控制器。我使用代理尝试创建一个progressWindow,它将运行代码并打印得很好,但代码是任意的。

I have the following 2 controllers listed below. I'm using delegation to try and create a progressWindow which will run code and print it nicely but where the code is arbitrary.

闭包是由符合协议(在我的case SyncViewController),但我想更改progressWindowViewController的UI从SyncViewControllers codeToRun {}关闭。我如何这样做?

The closures are defined by the class conforming to the protocol (in my case SyncViewController), but I want to change the UI of the progressWindowViewController from SyncViewControllers codeToRun {} closure. How do I do this?

SyncViewController.swift

import UIKit

class SyncViewController: UIViewController, progressWindowDelegate {

    var codeToRun = {
            //(self as! ProgressWindowViewController).theTextView.text = "changed the text"
            print("code to run")
    }
    var codeToCancel = {print("code to cancel")}
    var titleToGive = "Starting Sync..."

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func yesSyncButtonAction(sender: UIButton) {
        //Segue to the ProgressWindowViewController...

    }

    @IBAction func noSyncActionButton(sender: UIButton) {
        tabBarController?.selectedIndex = 1 //assume back to inventory section
    }

    // MARK: - Navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "SyncToProgressSegue"){
            let progressWindow = segue.destinationViewController as! ProgressWindowViewController

            progressWindow.controllerDelegate = self //sets the delegate so we have reference to this window still.

        }
    }

}

ProgressWindowViewController.swift

import UIKit

protocol progressWindowDelegate{
    var titleToGive : String {get}
    var codeToRun : ()->() {get}
    var codeToCancel : ()->() {get}
}


class ProgressWindowViewController: UIViewController {

    @IBOutlet weak var theTextView: UITextView!
    @IBOutlet weak var theProgressBar: UIProgressView!
    @IBOutlet weak var navItemLabel: UINavigationItem!

    //Sets delegate
    var controllerDelegate:progressWindowDelegate!

    override func viewDidLoad() {
        super.viewDidLoad()

        navItemLabel.title! = controllerDelegate.titleToGive

        dispatch_async(dispatch_get_main_queue(),{
            self.controllerDelegate.codeToRun() //Will run code accordingly.
        })

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func cancelNavItemButtonAction(sender: UIBarButtonItem) {
        dispatch_async(dispatch_get_main_queue(),{
            self.controllerDelegate.codeToCancel()
        })
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

他可以使用的例子是下载数千个库存记录的图像,这将打印库存细节,当他们抓住他们进入progressWindow。

An example of how his might be used is downloading thousands of inventory records with images, which would print the inventory details as it grabs them into the progressWindow.

但是这progressWindow也可以用于其他大/小任务,需要打印特定的东西到progressWindow文本区域(如登录,因此来自不同的视图控制器,而不是我的示例中的同步)。

But this progressWindow could also be used for other large/small tasks that need to print particular stuff into the progressWindow textarea (like logging in and therefore coming from a different view controller than sync in my example). The idea is to make it a dynamic class.

推荐答案

而不是创建一个变量,只是使用一个函数/方法?

Instead of creating a variable, just use a function/method?

override func viewDidLoad() {
    super.viewDidLoad()

    dispatch_async(dispatch_get_main_queue(),{
        self.controllerDelegate?.codeToRun(self)
    })
}

protocol progressWindowDelegate : class {
    var titleToGive : String {get}
    func codeToRun(progressWindowViewController:ProgressWindowViewController)
    var codeToCancel : ()->() {get}
} 

class SyncViewController: UIViewController, progressWindowDelegate {

func codeToRun(progressWindowViewController:ProgressWindowViewController) {
    print("code to run")
}


b $ b

也使委托弱和可选:

Also make delegate weak and optional:

delegate weak var controllerDelegate:progressWindowDelegate? = nil

这篇关于如何快速闭包引用它的类的运行的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆