在我正在开发的应用程序中,我需要在点击按钮时更新2个视图控制器 . 我设法更新包含按钮的视图控制器,但我无法更新其他视图控制器的内容 .
我尝试通过以下两种方式实现:首先,我在按钮的视图控制器中创建了一个委托变量(使用协议),并将其值设置为另一个视图控制器:
var delegate: WeatherServiceDelegateForcast? = ViewController2()
因为ViewController2是我试图使用委托更新的视图控制器 .
协议:
protocol WeatherServiceDelegateForcast{
func SetForcast(forcast: ForcastInfo)
}
viewController2中的SetForcast函数
func SetForcast(forcast: ForcastInfo) {
self.day1Label.text = ....
}
问题是,当执行函数SetForcast时,day1label的IBOutlet为零,因此无法更新 . 我想这是因为视图控制器尚未加载,但我无法找到加载它的方法 .
其次,我尝试使用segue(没有委托)将数据传递给viewcontroller2 . 这有效,但只有当我使用类型show为segue和我的应用程序时,它是不会打开它是至关重要的 . 当我尝试使用segue而不打开viewcontroller2(按类型自定义)时,它再次无法工作,无法识别IBOutlets .
有什么建议如何将数据传递给viewcontroller2而不打开它?
edit:
这是我使用的代码:
当轻触viewcontroller1中的按钮时,它从文本字段中获取数据并从其属性气象服务(可以工作)调用该函数 .
self.weatherService.GetForcast(textField.text!)
GetWeather获取城市的天气,从类型预测中创建变量,然后:
if self.delegate2 != nil
{
dispatch_async(dispatch_get_main_queue(), {
self.delegate2?.SetForecast(forecast)
})
}
因为delegate2是weatherService的属性,它引用了viewcontroller2,这就是它在weatherService类的开头定义的方式:
var delegate2: WeatherServiceDelegateForecast? = ViewController2()
和WeatherServiceForcast是协议:
protocol WeatherServiceDelegateForcast
{
func SetForecast(forecast: ForecastInfo)
}
然后,根据调试器,它使用正确的预测变量执行viewcontroller2的SetForecast:
func SetForcast(forcast: ForcastInfo) {
self.day1 = String(round(forcast.day[0])) + "-" + String(round(forcast.night[0]))
self.day2 = String(round(forcast.day[1])) + "-" + String(round(forcast.night[1]))
self.day3 = String(round(forcast.day[2])) + "-" + String(round(forcast.night[2]))
self.day4 = String(round(forcast.day[3])) + "-" + String(round(forcast.night[3]))
self.day5 = String(round(forcast.day[4])) + "-" + String(round(forcast.night[4]))
self.day6 = String(round(forcast.day[5])) + "-" + String(round(forcast.night[5]))
self.day7 = String(round(forcast.day[6])) + "-" + String(round(forcast.night[6]))
}
因为day1-7是viewController2类中的变量,我之后想要更新viewController2的标签,这就是这些变量的定义方式:
var day1 = String()
var day2 = String()
var day3 = String()
var day4 = String()
var day5 = String()
var day6 = String()
var day7 = String()
在viewDidLoad我把代码更新为变量day1-7的字符串,但它似乎首先调用该函数,然后它调用set forecast并更新变量 .
override func viewDidLoad() {
// Do any additional setup after loading the view.
self.day1Label.text = self.day1
self.day2Label.text = self.day2
self.day3Label.text = self.day3
self.day4Label.text = self.day4
self.day5Label.text = self.day5
self.day6Label.text = self.day6
self.day7Label.text = self.day7
}
2 回答
为什么不在
viewWillAppear
或viewDidLoad
中更新viewController2
的内容?视图控制器不会加载其视图和子视图,直到它需要在屏幕上显示它们 . 因此,如果您不打算显示viewController2
的视图,则不会加载viewController2
.一个干净的方式来实现你想要的是:
在
viewController2
中有一个单独的属性来存储数据在
viewController1
中设置属性的内容然后根据您刚设置的属性更新
viewDidLoad
或viewWillAppear
中viewController2
的视图 .Edit
尝试改变这个:
至
异步块内的代码将异步执行,因此
viewWillAppear
或viewDidload
可能被称为 before 这些属性已设置 . 这就是为什么这些值是“” . 此外,这里不需要使用异步块,你在SetForcast
中所做的只是设置属性值,它们几乎立即完成 .你根本做不到这一点 .
如果未加载
ViewController2
,则不会 never 获取数据 .首先必须初始化它,然后你可以给它数据,而不显示它 .
您只需要执行“alloc-init”将其加载到变量中 . 你提供数据 .