Swift / iOS:加载视图控制器

时间:2017-01-03 21:57:53

标签: ios swift xcode uiviewcontroller viewdidload

我正在构建一个应用程序(在XCode 8.2.1中),其中一些对象显示在2D板上,当用户点击其中一个对象时,应该将一些信息作为样式模态信息框显示出来。我的设计是将信息写在一个单独的视图控制器中,我会在需要时显示。

我为第二个视图控制器设计了一个基本存根,并在界面构建器中为其添加了一个标签。然后我将此标签ctrl链接到我的自定义VC类:

class InfoViewController: UIViewController {
    @IBOutlet weak var info: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    func displayInfo() {
        info.attributedText = NSAttributedString(string: "abc")
    }
}

但是,当我测试我的应用并点按该对象时,即使在我的自定义VC类的info方法中,nil字段也是viewDidLoad()。我显示VC的方式如下:

let infoViewController = InfoViewController()
infoViewController.modalPresentationStyle = .overCurrentContext
self.present(infoViewController, animated: true, completion: nil)
infoViewController.displayInfo()

(注意:最后我只有一个InfoViewController的单个实例,但这仅用于测试。我不希望全局实例会有任何区别吗?)

正如我所说,无论是在viewDidLoad()方法内还是在displayInfo()方法中,info总是nil,因此设置其attributedString属性崩溃的应用程序。我认为present方法可能是异步调用的,我尝试从displayInfo()内部调用viewDidLoad(),但这没有任何区别。

任何人都可以告诉我我忘记了什么会让我的IBOutlet正确初始化吗?

谢谢!

大卫

3 个答案:

答案 0 :(得分:16)

问题是InfoViewController()的引用,它独立于任何故事板场景实例化视图控制器。您想使用instantiateViewController

let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController
infoViewController.modalPresentationStyle = .overCurrentContext
present(infoViewController, animated: true) {
    infoViewController.displayInfo()
}

几点说明:

  • 这假定(a)你已经在故事板中给出了一个“故事板id”; (b)您已将该场景的基类设置为InfoViewController

  • 请注意,我在displayInfo的完成处理程序中调用了present,因为您可能不希望在场景出现并且已连接出口之前调用该对象。

或者,您可以在实例化后立即更新InfoViewController的非出口属性,然后让viewDidLoad获取这些属性并更新出口,例如:

class InfoViewController: UIViewController {
    var info: String!
    @IBOutlet weak var infoLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        infoLabel.attributedText = NSAttributedString(string: info)
    }
}

注意,我将@IBOutlet名称更改为infoLabel并添加了名为String的{​​{1}}属性。这往往是惯例,出口带有一些后缀表示控件的类型,模型对象,如info属性,没有后缀。 (您只需要确保在IB中的连接检查器中删除旧的插座,这样您就不会遇到这些属性名称更改的问题。)

无论如何,你可以这样做:

String

关键点是在实例化之后不要立即尝试更新场景的出口,但要确保在推迟let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController infoViewController.info = "abc" infoViewController.modalPresentationStyle = .overCurrentContext present(infoViewController, animated: true, completion: nil) 之前推迟它。

答案 1 :(得分:1)

我取代

let vc = CCDetailViewController()

。通过

let vc = self.storyboard?.instantiateViewController(withIdentifier: "CCDetailViewController")

<强>最后

self.present(vc!, animated: true, completion: nil)

现在有效......

答案 2 :(得分:0)

就我而言,我为相同的类创建了新的视图控制器。最终在情节提要中有两个视图控制器,但都指向同一个类。删除旧的视图控制器后,一切正常。

希望对某人有帮助。