如何从另一个类访问ViewController中的IBOutlet?

时间:2015-12-24 05:46:42

标签: ios swift

我有一个GCDAsyncUdpSocketDelegate的课程。现在我通过UDP(在后台线程中)获取一些数据,并且需要在我的ViewController中使用IBOutlet显示该数据。但ViewController只是一个类。它的对象实例在哪里定义?它叫什么名字?我该怎么做才能访问它,或者它的一个属性,方法?我已经看过这个UIApplication.sharedApplication().keyWindow?.rootViewController方法,但这并不能保证我想要访问的确切ViewController,我想。

2 个答案:

答案 0 :(得分:1)

我不知道您的应用的确切结构,但您可以尝试这样的事情:

let rootViewController = UIApplication.sharedApplication().keyWindow?.rootViewController

if let customViewController = rootViewController as? CustomViewController {

    customViewController.label.text = theData
}
else{ 
    let customViewController = storyoboard!.instantiateViewControllerWithIdentifier("CustomViewControllerID")
    // (This assumes CustomViewController is defined in the same 
    // storyboard as the view controller running this code. Otherwise, 
    // you need to get a reference to the storyboard first).

    rootViewController.presentViewController(customViewController, animated:true)

    customViewController.label.text = theData
}

编辑:如果从您的导航中获取了接收异步服务器数据的对象(顺便打一个好电话),您可以拥有它:

  1. 将数据存储在它将保留的某个位置,即使所述对象已取消分配 (或者,如果适用的话,将所述对象设为单身)。

  2. 在数据可用后发布系统通知(使用NSNotificationCenter),并让您的主ViewController“收听”(-addObserver:selector:name:object)。发布通知并调用通知处理程序时,视图控制器可以从其(持久)位置(如果选择该路径,文件或上述单例的属性)检索数据。

  3. 最后,对于在实例化ViewController时数据已经可用的情况,请检查数据可用性并检索它是否存在于例如viewDidLoad()中。您的主视图控制器from openerp import api, fields, models class stock_change_product_qty(models.Model): _inherit = 'stock.change.product.qty' new_quantity = fields.Float(string='Qty in Boxes', default=1.0), squ_meter = fields.Float(related='product_id.squ_meter', string='Square Meter', default=1.0), qty_char = fields.Float('Qty in M.sqr', compute='_compute_qty_char'), } @api.one @api.depends('new_quantity', 'squ_meter') def _compute_qty_char(self): for record in self: record.qty_char = record.new_quantity * record.squ_meter

答案 1 :(得分:1)

有很多方法可以实现这一目标,

<强> 1。使用协议或代理

你说“我的课程是 GCDAsyncUdpSocketDelegate 。”在该类中编写协议实现并使视图控制器订阅该委托,当您获得GCDAsyncUdpSocketDelegate的委托回调时,需要检查并将自定义委托发送到视图控制器,将数据作为参数传递给委托方法。在视图控制器中获取数据并更新IBOutlet。

<强> 2。使用NSNotificationCenter(肮脏的做事方式,但要小心)

在您的视图控制器类中添加一个观察者,用于发布您要发布的通知,

NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateUI:", name: "didRecieveDataFromUDP", object: nil)

在VC中添加方法

 func updateUI(notifObject:NSNotification){
  let responseString = notifObject.object
  self.yourOutlet.string = responseString
}

并在完成VC后删除通知观察器。 在GCDAsyncUdpSocketDelegate委托类中,当您收到带有结果的回调时触发此通知,

  NSNotificationCenter.defaultCenter().postNotificationName("didRecieveDataFromUDP"", object: theResposenObjectYouNeedToSend)

第3。使用sharedInstances或误用AppDelegate(不推荐)

创建将在整个应用程序生命周期中存在的共享实例或单例类,并使用它们来存储/检索来自任何类或任何线程的数据。

希望这有帮助,我希望你选择第一种或第二种方式。