Ich habe nur wenige Beiträge für dieses Problem gefunden, aber keiner von ihnen hat mein Problem gelöst.
Sag wie ich ..
- ViewControllerA
- ViewControllerB
Ich habe versucht, ViewControllerB als Unteransicht in ViewControllerA hinzuzufügen, aber es wird ein Fehler wie " fatal error: unexpectedly found nil while unwrapping an Optional value
" ausgegeben .
Unten ist der Code ...
ViewControllerA
var testVC: ViewControllerB = ViewControllerB();
override func viewDidLoad()
{
super.viewDidLoad()
self.testVC.view.frame = CGRectMake(0, 0, 350, 450);
self.view.addSubview(testVC.view);
// Do any additional setup after loading the view.
}
ViewControllerB ist nur ein einfacher Bildschirm mit einer Beschriftung.
ViewControllerB
@IBOutlet weak var test: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
test.text = "Success" // Throws ERROR here "fatal error: unexpectedly found nil while unwrapping an Optional value"
}
BEARBEITEN
Mit der vorgeschlagenen Lösung aus den Benutzerantworten verlässt ViewControllerB in ViewControllerA den Bildschirm. Der graue Rand ist der Rahmen, den ich für die Unteransicht erstellt habe.
quelle
ViewControllerB
zuViewControllerA
,ViewControllerB
wird der Bildschirm abgehend. Ich habe meinen Beitrag mit dem Screenshot des Simulators bearbeitet.frame
manuell eingestellt. Oder wenn Sie ausschaltentranslatesFrameIntoConstraints
(oder wie auch immer es heißt) und Sie wahrscheinlich auch programmgesteuert Einschränkungen hinzufügen können. Wenn Sie jedoch die Unteransicht hinzufügen, müssen Sie den Rahmen auf die eine oder andere Weise festlegen, genau wie bei allen programmgesteuert hinzugefügten Unteransichten.controller.view.frame = UIScreen.mainScreen().bounds
addSubview
, ist die Stammansicht des untergeordneten Controllers per Definition eine Unteransicht der Ansicht, zu der Sie sie hinzugefügt haben. Sie müssen lediglich Einschränkungen zwischen der Stammansicht des untergeordneten Controllers und der Ansicht hinzufügen, zu der Sie sie gerade als Unteransicht hinzugefügt haben.Danke an Rob. Hinzufügen einer detaillierten Syntax für Ihre zweite Beobachtung:
let controller:MyView = self.storyboard!.instantiateViewControllerWithIdentifier("MyView") as! MyView controller.ANYPROPERTY=THEVALUE // If you want to pass value controller.view.frame = self.view.bounds self.view.addSubview(controller.view) self.addChildViewController(controller) controller.didMoveToParentViewController(self)
Und um den Viewcontroller zu entfernen:
self.willMoveToParentViewController(nil) self.view.removeFromSuperview() self.removeFromParentViewController()
quelle
addChildViewController
, Sie nicht nennenwillMoveToParentViewController
. Wenn SieaddChildViewController
anrufen, wird es für Sie angerufen. Siehe Hinzufügen und Entfernen eines untergeordneten Elements im View Controller-Programmierhandbuch für iOS. Aus diesem Grund würde ich persönlich immeraddChildViewController
sofort nach dem Instanziieren anrufen , aber bevor ich es konfiguriere.This code will work for Swift 4.2. let controller:SecondViewController = self.storyboard!.instantiateViewController(withIdentifier: "secondViewController") as! SecondViewController controller.view.frame = self.view.bounds; self.view.addSubview(controller.view) self.addChild(controller) controller.didMove(toParent: self)
quelle
willMove
.addChild
macht das für dich Siehe diewillMove
Dokumentation . Die Sequenz ist also (1)addChild
; (2) Konfigurieren Sie die Ansicht des untergeordneten VC und fügen Sie sie der Ansichtshierarchie hinzu. und (3) AnrufdidMove(toParent:)
Zum Hinzufügen und Entfernen von ViewController
var secondViewController :SecondViewController? // Adding func add_ViewController() { let controller = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController")as! SecondViewController controller.view.frame = self.view.bounds self.view.addSubview(controller.view) self.addChild(controller) controller.didMove(toParent: self) self.secondViewController = controller } // Removing func remove_ViewController(secondViewController:SecondViewController?) { if secondViewController != nil { if self.view.subviews.contains(secondViewController!.view) { secondViewController!.view.removeFromSuperview() } } }
quelle
willMove
. Wie diewillMove
Dokumentation sagt,addChild
erledigt das das für Sie.func callForMenuView () {
if(!isOpen) { isOpen = true let menuVC : MenuViewController = self.storyboard!.instantiateViewController(withIdentifier: "menu") as! MenuViewController self.view.addSubview(menuVC.view) self.addChildViewController(menuVC) menuVC.view.layoutIfNeeded() menuVC.view.frame=CGRect(x: 0 - UIScreen.main.bounds.size.width, y: 0, width: UIScreen.main.bounds.size.width-90, height: UIScreen.main.bounds.size.height); UIView.animate(withDuration: 0.3, animations: { () -> Void in menuVC.view.frame=CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width-90, height: UIScreen.main.bounds.size.height); }, completion:nil) }else if(isOpen) { isOpen = false let viewMenuBack : UIView = view.subviews.last! UIView.animate(withDuration: 0.3, animations: { () -> Void in var frameMenu : CGRect = viewMenuBack.frame frameMenu.origin.x = -1 * UIScreen.main.bounds.size.width viewMenuBack.frame = frameMenu viewMenuBack.layoutIfNeeded() viewMenuBack.backgroundColor = UIColor.clear }, completion: { (finished) -> Void in viewMenuBack.removeFromSuperview() }) }
quelle
Dank Rob wurde die Swift 4.2-Syntax aktualisiert
let controller:WalletView = self.storyboard!.instantiateViewController(withIdentifier: "MyView") as! WalletView controller.view.frame = self.view.bounds self.view.addSubview(controller.view) self.addChild(controller) controller.didMove(toParent: self)
quelle
willMove
. Wie diewillMove
Dokumentation sagt,addChild
erledigt das das für Sie. Es nützt nichts, wenn man es zweimal nennt.Bitte lesen Sie auch die offizielle Dokumentation zur Implementierung eines benutzerdefinierten Containersicht-Controllers:
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html#//apple_ref/doc/uid/TP40007457-CH11-SW1
Diese Dokumentation enthält viel detailliertere Informationen zu jeder Anweisung und beschreibt auch, wie Übergänge hinzugefügt werden.
Übersetzt nach Swift 3:
func cycleFromViewController(oldVC: UIViewController, newVC: UIViewController) { // Prepare the two view controllers for the change. oldVC.willMove(toParentViewController: nil) addChildViewController(newVC) // Get the start frame of the new view controller and the end frame // for the old view controller. Both rectangles are offscreen.r newVC.view.frame = view.frame.offsetBy(dx: view.frame.width, dy: 0) let endFrame = view.frame.offsetBy(dx: -view.frame.width, dy: 0) // Queue up the transition animation. self.transition(from: oldVC, to: newVC, duration: 0.25, animations: { newVC.view.frame = oldVC.view.frame oldVC.view.frame = endFrame }) { (_: Bool) in oldVC.removeFromParentViewController() newVC.didMove(toParentViewController: self) } }
quelle