我无法从委托swift

时间:2016-02-22 10:14:26

标签: ios swift

我使用委托将通过JSON收集的数据传递给多个UIViewControllers

My setup is like this

我在ContainedViewController内为MainViewController创建programaticaly容器:

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

在我用另一个类的JSON(并首先在MainViewController 上传递它们)收集一些数据并将它们传递给MainViewController之后,我调用了该函数。我用于此目的的代码是:

func setForecast(forecast: Forecast) {
    self.delegateForecast?.loadOnContained(forecast)
    print("did forecast pass to delegate?")
    createContainer()
}

我还在MainViewController上设置了协议

protocol dataForContainedDelegate{
    func loadOnContained(forecast: Forecast)
}

变量

var delegateForecast: dataForContainedDelegate?

containedVC的代码是:

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

并且在我的输出窗口中,没有任何关于"预测加载"或者"日期设置",但是"包含负载" (在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

背后的原因

我希望当用户按下“设置城市”按钮以便能够选择城市,然后在MainViewController当前条件)和{上{I>}上解析来自JSON的数据{1}}内的{1}}(以后几天的预测)。

所以我的想法是

  1. 用户设置城市
  2. PageViewController被调用并将所有数据传递给containedVC
  3. WeatherServiceMainViewController func,我们在MainViewController上设置标签
  4. setWeatherMainViewController func,我们将数据传递给setForecast并动态创建页面。
  5. 但似乎数据永远不会到达MainViewController有什么原因吗?

    此外,我可以将数据加载到containedVC,如果我将其设为containedVC并且在viewDidLoad上调用containedVC,但这样我必须再次设置城市,而不是自动加载数据按下WeatherServiceDelegate按钮。

1 个答案:

答案 0 :(得分:0)

你给代表打电话的时间,实际上代表没有设定(即代表是零)。

根据我的理解,你只需要将数据从父viewController传递给child,你可以通过变量传递数据而不是使用delegate,如下所示,

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)

}