2017-07-16 6 views
0

私は故郷のレストランを表示し、メニュー、開店時間、住所を与えるためにこのアプリケーションを構築しています。私はこれは私がコレクションビュー機能で#selectorに渡す機能であるコレクションビューにレストランについての情報を表示するにはセレクタとローカル機能

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! RestaurantCollectionViewCell 

    cell.addressLabel.text = addressArray[indexPath.row] 
    cell.restaurantNameLabel.text = restaurantArray[indexPath.row] 
    cell.openingTimeLabel.text = openingTimeArray[indexPath.row] 
    cell.chosenRestaurantButton.addTarget(self, action: #selector(getProducts), for: .touchUpInside) 

    return cell 
} 

ここで、この機能を持っています。つまり、getProducts関数のコレクションビュー関数からインデックスパスが必要です。私は関数をネストできないので、ローカル関数についてのエラーがスローされます。どのように私はgetProducts関数でインデックスパスを取得することができますか?

func getProducts() { 
    let viewController = storyboard?.instantiateViewController(withIdentifier: "productsCollectionView") as! ProductsViewController 
    viewController.restaurantChosen = restaurantArray[indexPathVariable.row] 
    self.present(viewController, animated: true, completion: nil) 
} 

答えて

1

ボタンハンドラにindexPathを渡す必要はありません。ボタン自体からindexPathを決定することができます。

まず、パラメータとしてボタンを含めるようにボタンのハンドラを更新:

func getProducts(_ sender: UIButton) { 
} 

次にあなたがコレクションビュー内のボタンの位置からindexPathを計算することができます。

func getProducts(_ sender: UIButton) { 
    let position = sender.convert(CGPoint.zero, to: collectionView) 
    if let indexPath = collectionView.indexPathForItem(at: position) { 
     let viewController = storyboard?.instantiateViewController(withIdentifier: "productsCollectionView") as! ProductsViewController 
     viewController.restaurantChosen = restaurantArray[indexPath.row] 
     self.present(viewController, animated: true, completion: nil) 
    } 
} 

このコードはcell.chosenRestaurantButtonUIButtonであることを前提としています

let position = sender.convert(CGPoint.zero, to: collectionView) 
let indexPath = collectionView.indexPathForItem(at: position) 

はここにあなたの完全な方法です。また、ビューコントローラーがcollectionViewプロパティを持っていることを前提としています。

+0

心うわー、それは動作します吹き飛ばさ。ありがとうございました。 – user3103854

4

再利用可能なセル内のボタンでは、このようなことはできません。なぜあなたは、単にあなたのRestaurantCollectionViewCellサブクラスでデリゲートを使用しないのですか?

protocol RestaurantCollectionViewCellDelegate: class 
{ 
    func getProducts(indexPath: IndexPath) 
} 

class RestaurantCollectionViewCell: UICollectionViewCell 
{ 
    var indexPath: IndexPath! 
    weak var delegate: RestaurantCollectionViewCellDelegate? 

    @IBAction func buttonPressed(_ sender: UIButton) 
    { 
     self.delegate?.getProducts(indexPath: self.indexPath) 
    } 
} 

そして、あなたのCollectionViewコントローラで、単にこのようにデリゲートを割り当てます。

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, RestaurantCollectionViewCellDelegate 
{ 
    func getProducts(indexPath: IndexPath) 
    { 
     let viewController = storyboard?.instantiateViewController(withIdentifier: "productsCollectionView") as! ProductsViewController 
     viewController.restaurantChosen = restaurantArray[indexPath.row] 
     self.present(viewController, animated: true, completion: nil) 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCustomCVCell", for: indexPath) as! RestaurantCollectionViewCell 
     cell.indexPath = indexPath 
     cell.delegate = self 
     return cell 
    } 
} 
+0

FYI - あなたのコードはテキストフィールドデリゲートを使用していますが、質問はUIButtonに関するものです。 – rmaddy

+0

ありがとう、私はそれを編集しました。 –

関連する問題