1

I'm trying to create a detail view for documents. The top part of the detail view is a card-style layout of 90 pixels high, and below is a view pager switching between two controllers: InfoViewController (show some meta info) and DocumentViewController (show pdf).

I've laid out the top level controller (DetailViewController) in a xib file with two UIViews: viewForCard and viewForPager. However, the outlets defined in InfoViewController and DocumentViewController are not yet initialized when their viewDidLoad method is called. Anyone have any idea why?

The main code in DetailViewController (constraints for the container views viewForCard and viewForPager have been set up in the xib file:

@IBOutlet weak var viewForCard: UIView!
@IBOutlet weak var viewForPager: UIView!

var pageViewController:UIPageViewController = UIPageViewController()
var infoVC:InfoViewController = InfoViewController()
var documentVC:DocumentViewController = DocumentViewController()

override func viewDidLoad() {
    super.viewDidLoad()

    pageViewController.delegate = self
    pageViewController.dataSource = self
    addChildViewController(pageViewController)
    pageViewController.setViewControllers([infoVC], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
    initLayout()
}

func initLayout(){
    var cardView:UIView = Card(document: document).contentView
    cardView.setTranslatesAutoresizingMaskIntoConstraints(false)

    var pagerView = pageViewController.view
    pagerView.setTranslatesAutoresizingMaskIntoConstraints(false)

    viewForCard.addSubview(cardView)
    viewForPager.addSubview(pagerView)

    let bindings = ["card": cardView, "pager": pagerView]
    viewForCard.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0.0-[card]-0.0-|", options: nil, metrics: nil, views: bindings))
    viewForCard.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-0.0-[card]-0.0-|", options: nil, metrics: nil, views: bindings))

    viewForPager.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0.0-[pager]-0.0-|", options: nil, metrics: nil, views: bindings))
    viewForPager.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-0.0-[pager]-0.0-|", options: nil, metrics: nil, views: bindings))
}

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?{
    if viewController == documentVC{
        return infoVC
    }else{
        return nil
    }
}

func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?{
    if viewController == infoVC{
        return documentVC
    }else{
        return nil
    }
}
Anthony De Smet
  • 2,265
  • 3
  • 17
  • 24
  • 1
    Have you called setViewControllers:... method on UIPageViewController, does it not crash the app. – Sandeep May 04 '15 at 10:39
  • Thanks! I've added this line: pageViewController.setViewControllers([infoVC], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil) But now I have a different problem: the outlets defined in InfoViewController and DocumentViewController (the ones in the pager) are not initialized when their viewDidLoad method is called. – Anthony De Smet May 04 '15 at 10:47
  • 1
    Not yet, I've updated my question. In any case your comment helped me forward, but I still don't know why the outlets are not initialized yet. They should be when viewDidLoad is called I suppose? – Anthony De Smet May 04 '15 at 10:53

3 Answers3

1

You should change:

var infoVC:InfoViewController = InfoViewController()
var documentVC:DocumentViewController = DocumentViewController() 

To:

var infoVC:InfoViewController = InfoViewController(nibName: "InfoViewController", bundle: nil)
var documentVC:DocumentViewController = DocumentViewController(nibName: "DocumentViewController", bundle: nil)
vien vu
  • 4,277
  • 2
  • 17
  • 30
0

Apparently the view controllers were initialized with nibname nil, which was why the outlets were not set.

Anthony De Smet
  • 2,265
  • 3
  • 17
  • 24
0

In Swift 5

Initialise the viewController like this.

let firstVC:FirstVC = storyboard?.instantiateViewController(withIdentifier: "FirstVC") as! FirstVC

pageController.setViewControllers([firstVC], direction: .forward, animated: true, completion: nil)
Divyansh Jain
  • 373
  • 2
  • 5