私は次のものを持っています
CustomCellクラスを使用するセルにNIB(.xibファイル)を使用しました。このカスタムセルクラスは、セルのボタンをタッチするためのIBActionを処理します。 ViewControllerとその中のいくつかの変数を参照したいと思います。どのようにそれを行うべきですか(ViewControllerにアクセスする)?
ありがとう!
セルとView Controllerの間にこの種の依存関係を作成することはしません。これにより、アーキテクチャがより複雑になり、セルが再利用できなくなります。
委任パターンを使用することをお勧めします。これは少し複雑に聞こえるかもしれません-既に使用している場合でも(UITableViewDelegate
は典型的な例です):
MyCellProtocol
でプロトコルdidTapCell
を作成し、UITableViewCell
および/またはView Controllerに渡すカスタムデータを受け入れますweak var cellDelegate: MyCellProtocol?
_didTapXXX
ハンドラーまたはセルのdidSelectRowAtIndexPath
で、self.cellDelegate?.didTapCell()
を呼び出し、期待されるパラメーターを渡しますMyCellProtocol
を実装しますcellForRowAtIndexPath
で、セルの作成/デキュー時に、そのcellDelegate
プロパティをself
に設定しますこの時点で、セルでタップが行われると、View ControllerのdidTapCell
メソッドが呼び出され、そこから必要なことを実行できます。
重要な点は、セルにセルのタップ/選択を処理させるのではなく、View Controllerに通知してジョブを実行させることです。
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
セル内
if let myViewController = parentViewController as? MyViewController {
print(myViewController.title)
}
私はあなたがそれをするべきではないと思います、おそらくあなたは何か間違ったことをしていると思いますが、本当に本当に必要な場合は、CustomCell
クラスにプロパティがあります。
var viewController : UIViewController
次に、cellForRowAtIndexPath
にセルを作成するときにプロパティを設定します
cell.viewController = self
その後、セルコード内からView Controllerに簡単にアクセスできます。
self.viewController.doSomething()
しかし、繰り返しますが、私の意見では、コードを再設計する必要があります。セルはコントローラーを気にするべきではありません。自分自身を表示するだけで、他には何も気にしない
拡張機能を追加
extension UITableViewCell {
var viewControllerForTableView : UIViewController?{
return ((self.superview as? UITableView)?.delegate as? UIViewController)
}
}
以下のようにキャストします
if let viewController = self.viewControllerForTableView as? AnyController{
print(viewController.variable)
}
。
最善の方法は、委任を実装することです。デリゲートは、ボタンのクリックについてView Controllerに通知します。また、View Controller(上記のデリゲートのプロトコルに準拠している)がクリックイベントで実行するタスクを処理します。 (委任パターンのチュートリアルはオンラインで利用できます。委任の方法を知りたい場合は、それらを確認できます)。
これを試す前に実際に代替アプローチを使用したいという他のコメントを読んでくださいが、この拡張機能を使用すると、dataSource
である必要があるdelegate
およびUITableViewController
に到達できます
extension UITableViewCell {
var tableView:UITableView? {
get {
for var view = self.superview ; view != nil ; view = view!.superview {
if view! is UITableView {
return (view! as UITableView)
}
}
return nil
}
}
var tableViewDataSource:UITableViewDataSource? {
get {
return self.tableView?.dataSource
}
}
var tableViewDelegate:UITableViewDelegate? {
get {
return self.tableView?.delegate
}
}
}