40765


Swift3にて、tableViewControllerのセルのindexによって画面遷移先を指定し、遷移した先の画面同士でページ移動できるようにし、tableView（初期画面）に戻る時はNavigationControllerの戻るボタンで戻れるアプリを作りたいと思っております。

＜苦戦しているところ＞  
tableViewControllerのあるviewControllerからpageViewControllerにセグエで接続し、pageViewControllerからそれぞれページを表示させているのですが、その際に次のページに値(index)を渡そうとしているのですが、うまくいきません。

※ viewControllerにはNavigationControllerをEmbedしてあります。

TableViewControllerのあるViewController

[code]

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    @IBOutlet weak var tableView: UITableView!
    
    var indexCell:Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
    (略）
    
    //セルを作る
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let cellData = section0[(indexPath as NSIndexPath).row]
        cell.textLabel?.text = cellData.0
        cell.detailTextLabel?.text = cellData.1
        return cell
    }
    
    
    //セルがタップされた時の処理
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
        indexCell = indexPath.row
        performSegue(withIdentifier: "segue1",sender: self)
    
    }
    
    //セグエで移動する前にデータを受け渡す
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "segue1" {
            if let indexPath = self.tableView.indexPathForSelectedRow {     
                tableView.deselectRow(at: indexPath, animated: false)      
                if let pvc = segue.destination as? PageViewController {
                    pvc.received = indexCell       
                }
            }
        }
    }
    
    
    }
    
[/code]

pageViewController

[code]

    class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
    
    var contentVCs = [UIViewController]()
    
    var select:Int?
    
    //遷移後に渡される値を格納する
    var received:Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        dataSource = self
        delegate = self
    
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let fvc = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
        fvc.received = received
        let svc = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
        svc.received = received
        let tvc = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
        tvc.received = received
    
        contentVCs.append(fvc)
        contentVCs.append(svc)
        contentVCs.append(tvc)
    
        // タップされたcellのindexによって表示VCを分岐
        switch received! {
            case 0,3,6,9,12,15,18 :
            select = 0
            case 1,4,7,10,13,16,19 :
            select = 1
            case 2,5,8,11,14,17,20 :
            select = 2
        default :
            break
        }
    
        setViewControllers([contentVCs[select!]], direction: .forward, animated: true, completion: nil)
    
    }
    
    
    // MARK: - UIPageViewControllerDataSource
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let index = contentVCs.index(of: viewController), index != NSNotFound else { return nil }
        if index < contentVCs.count - 1 {
            return contentVCs[index + 1]
        } else {
            return nil
        }
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let index = contentVCs.index(of: viewController), index != NSNotFound else { return nil }
        if index > 0 {
            return contentVCs[index - 1]
        } else {
            return nil
        }
    }
    }
    
[/code]

FirstViewController（second,thirdも同じ）

[code]

    class FirstViewController: UIViewController {
    
    @IBOutlet weak var indexLabel: UILabel!
    
    //シーン移動の際に設定されるデータ
    var received:Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
    // 受取りdata確認用ラベル
    indexLabel.text = String(received!)
    
    }
    
    }
    
[/code]

このコードだと、セルのindex通りのvcを選んで表示されるのですが、ページをめくると同じindex番号のまま（タップした時のセルのindex)になってしまいます。ページが進んだらindex番号もカウントアップさせたりダウンさせたりしたいのですが、Before/Afterのところで値を渡せたらいいのかと思いましたが、適切なコードが書けず苦戦しております。  
長くなりましたが、分かる方いらっしゃいましたらご教授お願い致します。

＜回答を参考に修正したコード＞

[code]

    // MARK: - UIPageViewControllerDataSource
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let index = contentVCs.index(of: viewController), index != NSNotFound else { return nil }
        let nextIndex = index + 1
        if index == 0 {
            if let nextVC = contentVCs[nextIndex] as? SecondViewController {
                nextVC.received = nextIndex 
                return nextVC
            }
            return nil
        } else if index == 1 {
            if let nextVC = contentVCs[nextIndex] as? ThirdViewController {
                nextVC.received = nextIndex
                return nextVC
            }
            return nil
        } else {
            return nil
        }
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let index = contentVCs.index(of: viewController), index != NSNotFound else { return nil }
        let nextIndex = index - 1
        if index == 2 {
            if let nextVC = contentVCs[nextIndex] as? SecondViewController {
                nextVC.received = nextIndex
                return nextVC
            }
            return nil
        } else if index == 1 {
            if let nextVC = contentVCs[nextIndex] as? FirstViewController {
                nextVC.received = nextIndex
                return nextVC
            }
            return nil
        } else {
            return nil
        }
    }
    
[/code]


CC BY-SA 3.0
2018-01-05T16:24:26.307
40758
2018-01-09T09:57:11.307
2018-01-09T09:57:11.307
26719
26719
question
swift3
Swift3　PageViewControllerでの画面移動の際の値の渡し方


Afterなら`return contentVCs[index + 1]`としてるところで、

[code]

    // return contentVCs[index + 1]
    let nextIndex = index + 1
    if let nextVC = contentVCs[nextIndex] as? FirstViewController {
        nextVC.received = nextIndex
        return nextVC
    }
    return nil
    
[/code]

ですね。

ここでデータを渡そうというのは正しいと思います。「適切なコードが書けず」とのことですが、`ViewController`の配列に格納した遷移先のビューコントローラを`FirstViewController`のインスタンスとしてキャストせずにいて`received`にアクセスできなかったのではないでしょうか。このような場合は
`as` を使った型キャストが必要です。


CC BY-SA 3.0
2018-01-06T05:01:23.620
40765
2018-01-06T05:01:23.620
40758
answer