自定义容器:@IBOutlets nil 即使视图显示正确

Posted

技术标签:

【中文标题】自定义容器:@IBOutlets nil 即使视图显示正确【英文标题】:Custom container: @IBOutlets nil even though view is displaying correctly 【发布时间】:2015-03-08 21:52:15 【问题描述】:

我创建了一个 UIViewController。在这个视图控制器中,我有一个容器视图。

在代码中,我像这样实例化容器视图:

var answerButtons: AnswerButtonsViewController!

override func viewDidLoad() 
    super.viewDidLoad()

    answerButtons = AnswerButtonsViewController()
    answerButtons.delegate = self

    println(answerButtons.name) // This prints out the correct string
    println(answerButtons.answerOne) // This prints out nil
    println(answerButtons.buttons) // This prints out an empty array

    retrieveSelectedCategory(selectedCategory!)

但是容器视图肯定是实例化的,因为在容器视图类中我设置了 UIButton 的背景颜色,这在我的应用程序中正确显示。

这是我的容器视图中的代码:

@IBOutlet var answerOne: UIButton!
@IBOutlet var answerTwo: UIButton!
@IBOutlet var answerThree: UIButton!
@IBOutlet var answerFour: UIButton!
@IBOutlet var answerFive: UIButton!
@IBOutlet var answerSix: UIButton!
@IBOutlet var answerSeven: UIButton!
@IBOutlet var answerEight: UIButton!

var buttons: Array<UIButton> = []

var name = "Is this set"

var delegate: AnswerButtonsViewControllerDelegate?

override func viewWillAppear(animated: Bool) 
    addAnswerButtonsToArray()
    buttons.map(customiseButtons)


func addAnswerButtonsToArray() 
    buttons.append(answerOne)
    buttons.append(answerTwo)
    buttons.append(answerThree)
    buttons.append(answerFour)
    buttons.append(answerFive)
    buttons.append(answerSix)
    buttons.append(answerSeven)
    buttons.append(answerEight)


func customiseButtons(button: UIButton) 
    button.layer.cornerRadius = 5
    button.setTitleColor(UIColor.blackColor(), forState: .Normal)
    button.backgroundColor = GSNColor.veryLightGrayColor()

    var title: String! = button.titleLabel?.text
    title.replaceRange(title.startIndex...title.startIndex, with: String(title[title.startIndex]).capitalizedString)
    button.titleLabel?.text = title


@IBAction func answerButtonPressed(sender: UIButton) 
    delegate?.answerButtonPressed(sender)
 

按钮的 IBAction 也可以工作。

所以我不明白为什么我的属性 answerButtons 被启动并且 name 属性设置正常。但是,打印时属性为零并且数组为空。但是视图显示正确。

任何见解都将不胜感激,如果您需要更多详细信息,请告诉我。

编辑

这是带有连接的故事板图片:

【问题讨论】:

您是如何创建 IBOutlets 的?它们实际上是否连接到情节提要或 xib 中的按钮? 嘿 MirekE,我添加了一张显示故事板和连接的图片。如果有任何不清楚的地方,请告诉我。 【参考方案1】:

容器视图中嵌入的控制器与具有容器视图的控制器同时实例化。你不应该自己实例化它。你只需要得到它的引用。容器视图中的控制器是其子视图是容器视图的控制器的子视图控制器。而不是这个,

answerButtons = AnswerButtonsViewController() // this creates another instance that you never use, and is never on screen

你应该有这个,

answerButtons = self.childViewControllers[0] as AnswerButtonsViewController

【讨论】:

您好。我休息了一下,意识到我正在创建一个新实例。嗬!但是我不确定如何在 Swift 中获取实例。您的解决方案就像一个魅力。非常感谢。【参考方案2】:

在这里,您只是在实例化视图控制器。您只获得对它的引用。您必须使用情节提要实例化视图控制器

let SB: UIStoryboard = UIStoryboard(name: StoryboardName, bundle: Bundle.main)
let VC = SB.instantiateViewController(withIdentifier: StoryboardIdOfViewController)
if let _ = VC.view 
    //Do here

【讨论】:

【参考方案3】:

在加载视图之前,IBOutlet 将为零。您所做的只是实例化容器视图控制器,而不是显示或加载视图。

在调用 AnswerViewController 的 loadViewviewDidLoad 方法之前,IBOutlet 将不可用。

您可以查看:

if (answerButtons.isViewLoaded()) 


查看视图是否已加载。如果您希望加载视图,您需要访问控制器的视图属性,或者将视图作为子视图添加到视图层次结构中。

【讨论】:

嗨,杰夫,感谢您提供的方法。我已经添加了它并且可以确认它没有进入if语句。但是,我已经使用打印语句向我的 AnswerButtonsViewController 添加了一个 viewDidLoad 方法,并且该方法在其他打印语句之前被打印。另外我认为容器视图的全部意义在于保存控制器及其视图。为什么需要添加视图? 您需要执行嵌入转场吗?还是正在执行? 嗨,杰夫,感谢您的回复。 rdelmar 回答对问题进行了排序。我正在创建一个新实例,而不是获取界面生成器创建的实例。

以上是关于自定义容器:@IBOutlets nil 即使视图显示正确的主要内容,如果未能解决你的问题,请参考以下文章

iOS:dequeueReusableCellWithIdentifier 返回单元格,其中 IBOutlets 为 nil

IBOutlets 在 XIB 视图上为零

使用 IBOutlets 将视图控制器初始化为自定义视图

UITableView 自定义单元格 IBOutlets 为零

在为自定义视图调用 NSBundle(使用 loadNibName)后访问 IBOutlets 的最佳方法

IBOutlets/actions 和自定义子视图