2017-10-22 2 views
1

私は、2つのtableViews(upcomingTableViewとpastTransactionsTableView)を切り替えるsegmentedControlを持つticketsVCを持っています。これらの2つのtableViewは別々のファイルに作成されます。私は押して/テーブルビューから新しいVCを提示したいが、残念ながら私はこれらのtableViewsからnavigationControllerまたはpresentVCにアクセスすることはできません。Separated UITableViewからViewControllerをプッシュ/プレゼンテーション

マイようなアプローチ:このアプローチを採用する

class TicketsViewController: UIViewController { 

    let segmentedControllerView: SegmentedController = { 
     let sc = SegmentedController() 
     sc.translatesAutoresizingMaskIntoConstraints = false 
     sc.segmentedController.addTarget(self, action: #selector(segmentedControlValueChanged), for: .valueChanged) 
     sc.segmentedController.selectedSegmentIndex = 0 
     return sc 
    }() 

    let upcomingTableView: UpcomingTableView = { 
     let tv = UpcomingTableView(frame: .zero, style: .grouped) 
     tv.translatesAutoresizingMaskIntoConstraints = false 
     return tv 
    }() 

    let pastTransactionsTableView: PastTransactionsTableView = { 
     let tv = PastTransactionsTableView(frame: .zero, style: .grouped) 
     tv.translatesAutoresizingMaskIntoConstraints = false 
     return tv 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     //setupNavigationBar() 
     //setupViews() 
    } 

    @objc func segmentedControlValueChanged(_ sender: UISegmentedControl) { 
     let segmentedControl = sender 

     if segmentedControl.selectedSegmentIndex == 0 { 
      upcomingTableView.isHidden = false 
      pastTransactionsTableView.isHidden = true 
     } else { 
      upcomingTableView.isHidden = true 
      pastTransactionsTableView.isHidden = false 
     } 
    } 

//Both UpcomingTableView and PastTransactionsTableView 
//are created similar as below 
class UpcomingTableView: UITableView { 

    override init(frame: CGRect, style: UITableViewStyle) { 
     super.init(frame: frame, style: style) 

     delegate = self 
     dataSource = self 

     register(CustomCell.self, forCellReuseIdentifier: "cell") 

    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

extension UpcomingTableView: UITableViewDataSource, UITableViewDelegate { 
    //all the neccessary dataSource and delegate functions 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     let vc = TicketsViewController() 
     vc.present(UIViewController(), animated: true, completion: nil) 
     //This method cannot access TicketsVC 
    } 
} 

私の理由はupcomingTableViewとpastTransactionsTableView両方が非常に異なる細胞を示し、別のモデルを引くことです。誰も私がどのようにこれらのtableViews自体から新しいVCをプッシュ/プレゼンテーションすることができる任意のアドバイスを持っていますか?

+0

ちょうど私がself.presentingビュー –

+0

@HarshalBhavsarを提示する方法をdidselect使用して、それがコードを追加内部@HarshalBhavsar私はすでにチェックしている、メソッドにアクセスすることはできません。 – Koh

+0

チェックから' navigationController?.pushViewController() 'や' present'にアクセスすることはできません新しいVC –

答えて

0

私が正しく理解していれば、私は次のようになります: ticketsVCセグメント化されたコントロールを作成し、それを一番上に配置します。次に、テーブルのコンテナとして使用する単純なUIViewを追加します。これは、ストーリーボードに次のようになります。

enter image description here

私は常に内部の何かを持っているので、私はのUIViewController内のUITableViewを維持することを好みます。 2つのUIViewControllerを作成し、それぞれにUITableViewを追加し、これら2つのUIViewControllerのテーブルに関連して行う必要があるすべてを行います。

class SampleOneVC: UIViewController, UITableViewDelegate, UITableViewDataSource { 
// Your code for table 1 
} 

    class SampleTwoVC: UIViewController, UITableViewDelegate, UITableViewDataSource { 
// Your code for table 2 
} 

のUIViewControllerのための拡張機能を作成:で

// Don't forget to set the IDs in storyboard (Identity Inspector tab) for view controllers 
// field: 'Storyboard ID' 
// values: SampleOneVC & SampleTwoVC 
sampleOneVC = mainStoryboard.instantiateViewController(withIdentifier: "SampleOneVC") as! SampleOneVC 
sampleTwoVC = mainStoryboard.instantiateViewController(withIdentifier: "SampleTwoVC") as! SampleTwoVC 

今すぐ

extension UIViewController { 
    func configureChildViewController(childController: UIViewController, onView: UIView?) { 
     var holderView = self.view 
     if let onView = onView { 
      holderView = onView 
     } 
     addChildViewController(childController) 
     holderView!.addSubview(childController.view) 
     constrainViewEqual(holderView: holderView!, view: childController.view) 
     childController.didMove(toParentViewController: self) 
    } 


    func constrainViewEqual(holderView: UIView, view: UIView) { 
     view.translatesAutoresizingMaskIntoConstraints = false 

     let pinTop = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: holderView, attribute: .top, multiplier: 1.0, constant: 0) 
     let pinBottom = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: holderView, attribute: .bottom, multiplier: 1.0, constant: 0) 
     let pinLeft = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: holderView, attribute: .left, multiplier: 1.0, constant: 0) 
     let pinRight = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: holderView, attribute: .right, multiplier: 1.0, constant: 0) 

     holderView.addConstraints([pinTop, pinBottom, pinLeft, pinRight]) 
    } 
} 

var sampleOneVC: UIViewController! 
var sampleTwoVC: UIViewController! 

は、のviewDidLoadでそれらを初期化しticketsVCに戻り、変数を宣言し今、あなたはSampleOneVCとSampleTwoVCにdidSelectRowAt内seguesを使用することができるはず提示ビューコントローラ

self.configureChildViewController(childController: sampleOneVC, onView: myContainerView) 

を更新します。私はコード全体を書いていませんでしたが、別の方法でどのように実行できるか考えていることを願っています。

+0

ありがとう!私はあなたのコードをテストするために別のプロジェクトを作成しました。 – Koh

+0

ちょうど1つの質問ですが、 'childController.didMove(toParentViewController:self)'を行う必要があるかどうか質問したいと思います。機能的には、この行がなくても正しく動作します。私は目的を理解したい。 – Koh

+0

viewControllerをコンテナに追加するときはいつも使っています。正直言って、それを試してみませんでした。 :) [ここ](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621405-didmove)はドキュメントなので、より理解しやすくなります。 –

関連する問題