2016-10-29 2 views
0

質問:ボタンを介して別のViewControllerにUICollectionViewCellを移行する方法は?

どのように私は別のビューコントローラにUICollectionためのボタンを割り当てたUICollectionViewCellを移行するのですか?

概要:

  1. 私はUICollection、と私が持っている各画像のUICollectionCellsを作成しました。
  2. 私が見つけた各画像に対してCollectionCellオブジェクトを作成します。
  3. オブジェクトごとにイメージとボタンを作成できますが、セルのボタンのターゲットを設定すると、別のViewControllerにリダイレクトできなくなります。

試み:

私はいくつかの他の試みを読み、それらはすべて関数が元のビューコントローラから呼び出されることが必要。

button.addTarget(self,action:#selector(YourControllerName.buttonClicked(_:)), 
         forControlEvents:.TouchUpInside) 

現在のコード:

class CollectionViewCell: UICollectionViewCell { 
    var text: String! 
    var image_view: UIImageView! 
    var button: UIButton! 

    override func awakeFromNib() { 
     print("Number:" + card_text) 

     image_view = UIImageView(frame: contentView.frame) 
     image_view.contentMode = .scaleAspectFill 
     mage_view.clipsToBounds = true 
     contentView.addSubview(image_view) 

     let x_value = contentView.frame.width - contentView.frame.width 
     let y_value = (contentView.frame.height)/3 
     let rectangle = CGRect(x: x_value, y: y_value, width: contentView.frame.width, height: 40) 
     button = UIButton(frame: rectangle) 
     button.backgroundColor = UIColor.darkGray 
     button.setTitle(card_text, for: .normal) 
     button.layer.cornerRadius = 3 
     button.clipsToBounds = true 
     button.addTarget(self,action: #selector(ObjectViewCell.buttonPressed), for: .touchUpInside) 
     contentView.addSubview(button) 
    } 

    func buttonPressed(sender:UIButton!) { 
     print("Practicing: " + self.card_text) 
    } 
} 






class Selector: UIViewController 
{ 
    var collectionView: UICollectionView! 
    let base_image = UIImage(named: "blank") 
    var images = [UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank"), UIImage(named: "blank")] 

    @IBOutlet weak var main_view: UIView! 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     print("Loading view in Selector") 
     setupCollectionView() 
    } 

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

    func setupCollectionView() { 
     let layout = UICollectionViewFlowLayout() 

     // Add spacing around each cell. 
     layout.minimumLineSpacing = 10 
     layout.minimumInteritemSpacing = 10 

     // Set each cell size to the size of the image. 
     layout.estimatedItemSize = CGSize(width: (base_image?.size.width)!, height: (base_image?.size.height)!) 

     // Set the collection view to the size of the view frame. 
     collectionView = UICollectionView(frame: main_view.frame, collectionViewLayout: layout) 

     // Register all images with the CollectionViewCell object. 
     collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell") 

     // Set the background color. 
     collectionView.backgroundColor = UIColor.white 
     collectionView.delegate = self 
     collectionView.dataSource = self 

     // Add the collections view to the main view. 
     view.addSubview(collectionView) 
    } 
} 


extension Selector: UICollectionViewDelegate, UICollectionViewDataSource 
{ 
    func numberOfSections(in collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return images.count 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell 
     cell.card_text = String(indexPath.item + 1) 
     cell.awakeFromNib() 
     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { 
     let cardCell = cell as! ObjectViewCell 
     cardCell.image_view.image = images[indexPath.row] 
    } 
ビューコントローラから関数を呼び出す

let secondViewController:SecondViewController = SecondViewController() 

    self.presentViewController(secondViewController, animated: true, completion: nil) 
} 

ビューの現在のビューコントローラ内からコントローラを起動します

更新:

ここでは、私がやってしまったものです。私は皆のコメントと答えを読んで、UICollectionセルを生成したView Controller内で必要な変更をすべて行うことを決意しました。したがって、私は自分のロジックをCollectionViewCellオブジェクトから外し、代わりにセルの初期化ですべてのロジック/サブビューの追加を実行しました。

これで、View Controllerの移行方法を理解するだけで済みます。みんなありがとう。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) 
     let contentView = cell.contentView 
     let image_view = UIImageView(image: base_image) 

     image_view.contentMode = .scaleAspectFill 
     image_view.clipsToBounds = true 
     contentView.addSubview(image_view) 

     let x_value = contentView.frame.width - contentView.frame.width 
     let y_value = (contentView.frame.height)/3 
     let rectangle = CGRect(x: x_value, y: y_value, width: contentView.frame.width, height: 40) 
     let button = UIButton(frame: rectangle) 

     let text = String(indexPath.item + 1) 
     button.setTitle(text, for: .normal) 
     button.accessibilityHint = text 
     button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside) 
     contentView.addSubview(button) 
     return cell 
    } 



func buttonPressed(sender:UIButton!) { 
     print("Button pressed") 
     print(sender.accessibilityHint) 

     //let navController = UINavigationController(rootViewController: self) 
     // 2. Present the navigation controller 
     //self.present(navController, animated: true, completion: nil) 
    } 
+0

問題は、あなたの 'buttonPressed'は何かをdoesntのことです。 – matt

+0

私はそれを知っています!別のView Controllerに移行しようとする試みを取り除いたからです。コンパイルエラーが発生する。 – Speakeasys

+0

自分自身で 'awakeFromNib'を呼び出すべきではありません。これにより、再利用時にセルに複数のサブビューが表示されます。既存のテキストフィールドとテキストプロパティが変更されたとき、Paulw11 @セッター – Paulw11

答えて

1

問題は、あなたのボタンのターゲットは細胞であり、そのためbuttonPressedアクション機能は、セル内に配置されていることです。これはかなり愚かなことです。あなたが正しく言うように、presentにそれを送るためのビューコントローラなしでは呼び出せないからです。

ボタンのターゲット/セレクタはcellForItemAt:に設定されています。このようにして、selfビューコントローラであり、ターゲットをselfに設定できます。しかし、あなたはそれをしなかった!

したがって、セルを制御するビューコントローラにセルから移動する必要があります。

しかし、方法があります。レスポンダチェーンを歩いているのはです。ボタンにUIResponder変数を設定します。

var responder : UIResponder = self 

今ループ、チェーンまで一歩を歩いてrespondernextを呼び出す:

responder = responder.next 

たびに、このレスポンダがのUIViewControllerであるかどうかを確認します。そうであれば、ループを止めてpresentを送信してください!このように:問題はこの方法で解決することができるにもかかわらず

var responder : UIResponder = self 
repeat { responder = responder .next } while !(responder is UIViewController) 
let vc = responder as! UIViewController 
vc.present(// ... 

(それでも、私は最初の場所でこの混乱の中に自分自身を取得するために愚かだったと思う最初の場所でのビューコントローラターゲットを作るだろう。私の意見では、はるかに良いアイデアだった。)

+0

私はこれらの解決策のいずれかのファンではありません。 1)適切なカプセル化では、ViewControllerがCollectionViewCellのプロパティをリップリングしない、2)親ビューコントローラがスーパーハッキーであることを知るためにレスポンダチェーンを歩いていることが指示されます。デリゲートパターンを使用します。誰もがココアで期待していること。セルは、ユーザーが詳細ビューにナビゲートする方法の詳細を把握し、ViewControllerとViewControllerに指示します。 2つは疎結合され、懸念の分離を維持し、ViewControllerはボタンプレスの詳細について何も知らない。 –

+0

@JoshHomannあなたが言っていることが分かります。私はMVCを迂回しています。代わりに、ビューコントローラがそのロジックを決定するのを許可するのではなく、トランジションを制御できるようにする必要があります。このようにして私がどうやって行くのか知っていますか?理想的には、私は彼らが押すボタンに応じて別のビューにユーザーを送信したいと思います。これは、単一のパラメータを取る単一のビューであってもよい。 – Speakeasys

+0

@JoshHomann私は全く同意しない!セルは、純粋でシンプルなビューです。ビューコントローラはコントローラです。 _it_は思考をするべきです。そして、ビューコントローラ_qua_データソースは、セルのプロパティを通して最も確実に繰り返されます。それは正確には何をしているのですか? – matt

関連する問題