所有的IBOutlets都是nil。

4

你好,我正在使用以下代码初始化viewController:

 var aboutUsViewController = self.storyboard?.instantiateViewControllerWithIdentifier("AboutUsViewController") as AboutUsViewController

接下来,我切换到aboutViewController。然而,所有在aboutViewController上的IBOutlets都是nil!为什么会这样呢? 我正在使用MMDrawer库,以便拥有侧边栏菜单。

 var aboutUsViewController = self.storyboard?.instantiateViewControllerWithIdentifier("AboutUsViewController") as AboutUsViewController


        var aboutUsNavController = UINavigationController(rootViewController: aboutUsViewController)

        var appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate

        appDelegate.centerContainer!.centerViewController = aboutUsNavController
        appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)

在侧边栏中,我选择“关于我们”菜单项,然后创建AboutViewController并将其移动到左侧...问题是当我初始化我的控制器时,插座为nil。
当我使用pageViewController时,我也遇到了这样的问题。
class ViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {


let pageTitles = ["Title 1", "Title 2", "Title 3", "Title 4"]
var images = ["long3","long4","long1","long2"]
var count = 0


var pageViewController : UIPageViewController!

override func viewDidLoad() {
    super.viewDidLoad()
    reset()
    // Do any additional setup after loading the view, typically from a nib.
}

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

func reset() {
    /* Getting the page View controller */
    pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as UIPageViewController
    self.pageViewController.dataSource = self

    let pageContentViewController = self.viewControllerAtIndex(0)
    self.pageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)

    /* We are substracting 30 because we have a start again button whose height is 30*/
    self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height - 30)
    self.addChildViewController(pageViewController)
    self.view.addSubview(pageViewController.view)
    self.pageViewController.didMoveToParentViewController(self)
}



func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {

    var index = (viewController as PageContentViewController).pageIndex!
    index++
    if (index >= self.images.count){
        return nil
    }

    return self.viewControllerAtIndex(index)
}


func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    var index = (viewController as PageContentViewController).pageIndex!

    if index<=0 {
        return nil
    }
    index--
    return self.viewControllerAtIndex(index)
}

func viewControllerAtIndex(index : Int) -> UIViewController? {
    if((self.pageTitles.count == 0) || (index >= self.pageTitles.count)) {
        return nil
    }
    let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageContentViewController") as PageContentViewController

    pageContentViewController.imageName = self.images[index]
    pageContentViewController.titleText = self.pageTitles[index]
    pageContentViewController.pageIndex = index
    return pageContentViewController
}

func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
    return pageTitles.count
}

func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
    return 0
    }

}



class PageContentViewController: UIPageViewController {


@IBOutlet var imageViewMain: UIImageView!

@IBOutlet var labelMain: UILabel!

var pageIndex: Int!
var titleText: String!
var imageName: String!


override func viewDidLoad() {
    super.viewDidLoad()

    self.imageViewMain.image = UIImage(named:imageName)
    self.labelMain.text = self.titleText
    self.labelMain.alpha = 0.1
    UIView.animateWithDuration(1.0, animations:{ ()-> Void in
        self.labelMain.alpha = 1.0
    })
    // Do any additional setup after loading the view.
}

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


/*
// 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.
    }
    */

}

我遇到了标签和图像输出为空的问题!!!在使用MMDrawer库时我也遇到了同样的问题。情况相同,不使用segues! 我认为这是因为输出为空。


你已经扩展了这个内容,展示了你如何使用aboutUsViewController(谢谢),但是你没有告诉我们在哪里使用了这个视图控制器上的插座,它仍然是nil。哪个插座是nil?这个问题发生在哪里? - Rob
抱歉回复晚了。问题出现在aboutUSViewController上。在主面板上,我添加了标签并将它们拖到了aboutUSViewController中。我在viewdidload中设置标签的值。但是我遇到了一个奇怪的错误,所有标签输出都为nil。 - Yestay Muratov
我找到了答案。我创建了 UIPageViewController 而不是创建 UIViewController。 - Yestay Muratov
3个回答

17
我假设你正在创建场景后立即查看outlets(如果使用segues并尝试在prepareForSegue中使用outlets,也会出现此行为)。但是outlets直到你呈现/推入该场景、视图加载并调用viewDidLoad之后才会被连接好。
最重要的是,在viewDidLoad被调用之前不要尝试使用outlets(即不要在实例化场景后立即使用outlets)。相反,将所需数据传递到目标场景(例如String属性),然后目标的viewDidLoad应该填充outlet。
例如,您可能在AboutUsViewController中有一个属性:
var message: String!

当您实例化AboutUsViewController时,您需要设置该属性:

let aboutUsViewController = self.storyboard?.instantiateViewControllerWithIdentifier("AboutUsViewController") as AboutUsViewController // use `as!` in Swift 1.2

aboutUsViewController.message = "some message"

presentViewController(aboutUsViewController, animated: true, completion: nil)

然后,AboutUsViewControllerviewDidLoad 将使用该属性相应地填充插座:

override func viewDidLoad() {
    super.viewDidLoad()

    label1.text = message
}

但您永远不会让原始视图控制器尝试设置或调整目标场景的输出。这是AboutUsViewController的责任。


只是确认一下,您的输出是否正确连接?以下显示了两种确认它们已正确连接的方法。

当您在界面构建器中选择视图控制器,然后查看连接检查器时,您是否看到已连接您的输出?在下面的快照中,label1已连接,但label2没有连接:

enter image description here

或者当您查看代码并查看输出时,您是否看到左边缘中的实心点(表示已连接输出)或空点(表示未连接输出)?

enter image description here


嗨Rob,我正在使用MMDrawer库来实现侧边栏功能!所以我根本不使用perform segue。我只是创建一个视图控制器并将其移动到左侧...请参见上面,我编辑了我的问题。 - Yestay Muratov
明白了。(我只提到了segue,因为它们遇到了相同的问题,并试图帮助未来遇到这个问题的读者。)我的观点是有两个可能的问题:要么是在视图加载之前就使用了outlets(请记住,这不会在您实例化视图控制器时发生,而是稍后当视图实际呈现时发生),要么在IB中outlets没有正确连接。 - Rob
Rob,我在使用pageViewController时遇到了同样的问题。 - Yestay Muratov

3
您可以在iOS9及更高版本上使用此功能,在展示之前使用此函数:
    aboutUsViewController.loadViewIfNeeded()

0

我找到答案了。我创建的不是 UIViewController,而是 UIPageViewController!!!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接