一部のオブジェクトが2Dボードに表示されるアプリ(XCode 8.2.1)を作成しています。ユーザーがこれらのオブジェクトのいずれかをタップすると、スタイル付きのモーダル情報ボックスとしてそのオブジェクトに関する情報が表示されます。私の設計では、必要に応じて表示する別のViewControllerに情報を書き込むことです。
2番目のViewControllerの基本的なスタブを設計し、InterfaceBuilderでそれに単一のラベルを追加しました。次に、このラベルをカスタムVC class:
_class InfoViewController: UIViewController {
@IBOutlet weak var info: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
func displayInfo() {
info.attributedText = NSAttributedString(string: "abc")
}
}
_
ただし、アプリをテストしてオブジェクトをタップすると、カスタムのviewDidLoad()
メソッドでもinfo
フィールドはnil
になりますVC =クラス。VC)の表示方法は次のとおりです。
_let infoViewController = InfoViewController()
infoViewController.modalPresentationStyle = .overCurrentContext
self.present(infoViewController, animated: true, completion: nil)
infoViewController.displayInfo()
_
(注:最終的には、InfoViewController
のインスタンスは1つだけになりますが、これはテスト用です。グローバルインスタンスがあると違いが生じるとは思いませんか?)
私が言ったように、それがviewDidLoad()
メソッド内であろうとdisplayInfo()
メソッド内であろうと、info
は常にnil
であり、そのattributedString
属性はアプリをクラッシュさせます。 present
メソッドが非同期的に呼び出される可能性があると考えて、displayInfo()
の内部からviewDidLoad()
を呼び出してみましたが、違いはありませんでした。
IBOutlet
が正しく初期化されないようにするために、私が忘れたことを誰かに教えてもらえますか?
ありがとう!
ダビデ
問題は、ストーリーボードシーンに関係なくビューコントローラをインスタンス化する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
というプロパティをinfo
に追加したことに注意してください。これは慣例である傾向があり、アウトレットにはコントロールのタイプを示す接尾辞が付いており、String
プロパティなどのモデルオブジェクトには接尾辞がありません。 (これらのプロパティ名の変更に問題がないように、IBの接続インスペクターでその古いコンセントを削除することを確認する必要があります。)
とにかく、あなたはそれからすることができます:
let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController
infoViewController.info = "abc"
infoViewController.modalPresentationStyle = .overCurrentContext
present(infoViewController, animated: true, completion: nil)
重要な点は、シーンをインスタンス化した直後にシーンのアウトレットを更新しようとしないことですが、これはviewDidLoad
が呼び出されるまで延期されるようにしてください。
交換しました
let vc = CCDetailViewController()
あり
let vc = self.storyboard?.instantiateViewController(withIdentifier: "CCDetailViewController")
ついに
self.present(vc!, animated: true, completion: nil)
今それは動作します...
私の場合、同じクラスの新しいViewControllerを作成しました。ストーリーボードに2つのビューコントローラーが含まれることになりましたが、同じクラスを参照しています。古いViewControllerを削除した後、すべてが正常に機能しました。
それが誰かに役立つことを願っています。