I'm using delegates to pass data collected through JSON to several UIViewControllers
.
I create programaticaly the container for the ContainedViewController
inside the MainViewController
:
func createContainer(){
let controller: UIViewController = (storyboard?.instantiateViewControllerWithIdentifier("containedVC"))! as UIViewController
controller.view.frame = CGRect(x: 20, y: self.view.frame.height-220, width: self.view.frame.width-40, height: 200)
view.addSubview(controller.view)
self.addChildViewController(controller)
}
I call the function after I collect some data with JSON ( and pass them first on the MainViewController ) on another class and pass them to the MainViewController
. The code I use for this purpose is:
func setForecast(forecast: Forecast) {
self.delegateForecast?.loadOnContained(forecast)
print("did forecast pass to delegate?")
createContainer()
}
I've also set up a protocol on the MainViewController
:
protocol dataForContainedDelegate{
func loadOnContained(forecast: Forecast)
}
And a variable :
var delegateForecast: dataForContainedDelegate?
My code for the containedVC
is:
import UIKit
class ContainedViewController: UIViewController, UIPageViewControllerDataSource, dataForContainedDelegate {
var forecastService = MainViewController()
var pageViewController: UIPageViewController!
var pageDates: NSArray!
var pageHighTemps: NSArray!
var pageLowTemps: NSArray!
var pageDescriptions: NSArray!
//var pageImages: NSArray!
func loadOnContained(forecast: Forecast) {
print("forecast loaded")
self.pageDates = forecast.dates
print("dates set")
self.pageHighTemps = forecast.highTemps
self.pageLowTemps = forecast.lowTemps
self.pageDescriptions = forecast.descriptionsArray
createVCs()
}
func createVCs(){
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
let startVC = self.viewControllerAtIndex(0) as ContentViewController
let viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.forecastService.delegateForecast = self
print("contained load")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewControllerAtIndex(index: Int) -> ContentViewController{
if(self.pageDates.count == 0) || (index >= self.pageDates.count){ //MARK2: ---ERRON IN THIS LINE "fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
return ContentViewController()
}
let vc: ContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
vc.pageIndex = index
vc.dateText = self.pageDates[index] as! String
vc.highTmp = self.pageHighTemps[index] as! String
vc.lowTmp = self.pageLowTemps[index] as! String
vc.descText = self.pageDescriptions[index] as! String
//vc.weatherFile = self.pageImages[index] as! String
return vc
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound){
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound){
return nil
}
index++
if (index == self.pageDates.count){
return nil
}
return self.viewControllerAtIndex(index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return self.pageDates.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
When I run the app I get this screen
and on my output window there's nowhere anything about "forecast loaded" or "dates set", but there's "contained load" (which is under viewDidLoad
func):
self.weatherService.delegate = self **** at main
from DefaultsSet: Los Angeles
Weather Service class city: Los Angeles
Date: 21 Feb 2016 , High: 20.6 °C , Low: 10.0 °C, Text: Clear
Date: 22 Feb 2016 , High: 28.3 °C , Low: 12.8 °C, Text: Sunny
Date: 23 Feb 2016 , High: 27.8 °C , Low: 12.2 °C, Text: Partly Cloudy
Set Weather main view
did forecast pass to delegate?
contained load
The reason behind this mess
I want when the user press Set City button to be able to select a city and then the data from JSON to be parsed on the MainViewController
( Current Conditions ) and on the PageViewController
inside the the containedVC
( Forecast for the following days ).
So my thinking is
WeatherService
is called and pass all the data to MainViewController
setWeather
func on MainViewController
we set the label on MainViewController setForecast
func on MainViewController
we pass data to the containedVC
and create the pages dynamically. but it seems the data never arrive on the containedVC
. Any reasons for that?
Furthermore I can load data to containedVC
if I make it a WeatherServiceDelegate
and on viewDidLoad call setWeather(city: String)
but this way I have to set the city again and not automatically load the data on Set City
button pressed.
The time at which you call the delegate, actually the delegate was not set(ie delegate is nil).
From my understanding, you just need to pass the data from parent viewController to child for which you could just pass the data through a variable instead of using delegate, as shown below,
func createContainer(){
let controller: UIViewController = (storyboard?.instantiateViewControllerWithIdentifier("containedVC"))! as UIViewController
controller.data = forecast // like this
controller.view.frame = CGRect(x: 20, y: self.view.frame.height-220, width: self.view.frame.width-40, height: 200)
view.addSubview(controller.view)
self.addChildViewController(controller)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.