Search code examples
iosswiftuiviewcontrollerxcode7uipageviewcontroller

When I pass data from TableView to child PageViewController, it can go to next child


I have an UIViewController with a UITableView. Then I create a PageViewController with two viewcontroller. Pageview doesn't work if I pass data to child. If I change

setViewControllers([subjective], direction: .Forward, animated: true, completion: nil)

to

setViewControllers([firstVC], direction: .Forward, animated: true, completion: nil)

Pageview work but data don't pass. I don't have any idea about it. Help me please. Thanks

Code Work:

pageview controller class:

import UIKit

class PageVC : UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {

var lblhoten = String()
var lblngaysinh = String()
var lblsodt = String()

lazy var VCArr: [UIViewController] = {
    return [self.VCInstance("ThongTinBNPage2"),
            self.VCInstance("ThongTinBNPage3")]
}()

private func VCInstance(name: String) -> UIViewController {
    return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier(name)
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.dataSource = self
    self.delegate = self
    if let firstVC = VCArr.first {
        let subjective = self.storyboard?.instantiateViewControllerWithIdentifier("ThongTinBNPage2") as! VCSubjective
        subjective.lblhoten = lblhoten
        subjective.lblngaysinh = lblngaysinh
        subjective.lblsodt = lblsodt
        setViewControllers([subjective], direction: .Forward, animated: true, completion: nil)
    }
}

public func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    guard let viewcontrollerindex = VCArr.indexOf(viewController) else {
        return nil
    }

    let previousindex = viewcontrollerindex - 1


    guard previousindex >= 0 else {
        return VCArr.last
    }

    guard VCArr.count > previousindex else {
        return nil
    }

    return VCArr[previousindex]
}

public func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    guard let viewcontrollerindex = VCArr.indexOf(viewController) else {
        return nil
    }

    let nextindex = viewcontrollerindex + 1


    guard nextindex < VCArr.count else {
        return VCArr.first
    }

    guard VCArr.count > nextindex else {
        return nil
    }

    return VCArr[nextindex]
}

public func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
    return VCArr.count
}

// The selected item reflected in the page indicator.
public func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
    guard let firstviewcontroller = viewControllers?.first,
        let firstviewcontrollerindex = VCArr.indexOf(firstviewcontroller) else {
            return 0
    }

    return firstviewcontrollerindex
}

}

VCSubjective:

import UIKit

class VCSubjective: UIViewController {

@IBOutlet var hoten: UILabel!
@IBOutlet var ngaysinh: UILabel!
@IBOutlet var sodt: UILabel!

var lblhoten = String()
var lblngaysinh = String()
var lblsodt = String()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.        
    hoten.text = lblhoten
    ngaysinh.text = lblngaysinh
    sodt.text = lblsodt
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

Solution

  • The problem here is that you are referencing two completely different objects.

    In viewDidLoad you create ThongTinBNPage2 viewController and then add it to the viewControllers property of the pageViewController. However, the objects stored in VCArr are two totally different viewControllers.

    Let's think about it this way:

    1. When viewDidLoad is called you create viewController object #1
    2. Then you assign the viewController object #1 to the viewControllers object of the pageViewController making the value of viewControllers = [object #1]
    3. In pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? and pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? you reference the VCArr object. On the first call to VCArr, it lazily creates two completely different view controller objects [object #2, object #3]

    To fix this code you need to do the following:

    if let firstVC = VCArr.first {
        let subjective = firstVC   // DO NOT create different VC here
        subjective.lblhoten = lblhoten
        subjective.lblngaysinh = lblngaysinh
        subjective.lblsodt = lblsodt
        setViewControllers([subjective], direction: .Forward, animated: true, completion: nil)
    }