Reputation: 1742
I am adding a view having set of images(socialView)
inside a collection view cell(having other views also) on which a common click has to be performed. This click should not be same as collection view cell click.
I am thinking of adding UITapGestureRecognizer
for socialView
everytime in CollectionView
delegate method cellForItemAt
. But I want to know is it the right way? Moreover, i want to get the indexPath/position on which socialView
has been called.
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.socialViewTapped))
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "bidderAuctionCell", for: indexPath) as! BidderAuctionViewCell
cell.socialView.addGestureRecognizer(tapGestureRecognizer)
}
@objc func socialViewTapped() {
// Which item cell's socialview is clicked
}
UPDATE
I have done as per the below suggestions, but i am not able to get where should i add UITapGestureRecognizer in the custom cell. Following is the custom cell which i have created.
class CustomViewCell: UICollectionViewCell {
var index : IndexPath!
var socialViewDelegate : SocialViewDelegate!
@IBOutlet weak var socialView: UIView!
override init(frame: CGRect) {
super.init(frame:frame)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.viewTapped))
socialView.addGestureRecognizer(tapGestureRecognizer)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
@objc func viewTapped(){
socialViewDelegate.socialViewTapped(at: index)
}
}
The init function is not being called. I also tried to put in required init, but there the social view is not initialized. So getting crashed
FINAL ANSWER
class CustomViewCell: UICollectionViewCell {
var index : IndexPath!
var socialViewDelegate : SocialViewDelegate!
@IBOutlet weak var socialView: UIView!
override func awakeFromNib() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
socialView.isUserInteractionEnabled = true
socialView.addGestureRecognizer(tapGesture)
}
@objc func handleTap(){
socialViewDelegate.socialViewTapped(at: index)
}
}
protocol SocialViewDelegate {
func socialViewTapped(at index: IndexPath)
}
Upvotes: 5
Views: 10500
Reputation: 214
I hope this works if you still haven't find a way you use protocol like this, in your custom cell like this
import UIKit
protocol CustomDelegate {
func showData(indexPath: IndexPath?)
}
class CustomCell: UICollectionViewCell {
// properties
var delegate: CustomDelegate?
var selectedAtIndex: IndexPath?
// outlets
override func awakeFromNib() {
super.awakeFromNib()
myView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dothis)))
}
@objc func dothis(){
delegate?.showData(indexPath: selectedAtIndex)
}
@IBOutlet weak var myView: UIView!
}
write your view controller like this
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, CustomDelegate{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
cell.delegate = self
cell.selectedAtIndex = indexPath
return cell
}
func showData(indexPath: IndexPath?) {
if let ip = indexPath{
print("\(ip) is the index path for tapped view")
}
}
}
do tell if this helps
Upvotes: 1
Reputation: 2859
@Anurag you can solve this problem by using either of the following concepts Delegation, Closures, Notifications. I will suggest you go with the delegation pattern which iOS follows widely into its components like UITableView, UICollectionView etc.
Coding Example:
1. Your CollectionViewCell should look like this :
import UIKit
Protocol ViewTappedDelegate: class {
func viewTapped(_ photo : String) { }
}
class YourCell: UICollectionViewCell, UIGestureRecognizerDelegate {
@IBOutlet weak var containerView: UIView!
weak var delegate : ViewTappedDelegate?
override func awakeFromNib() {
let tapGesture = UITapGestureRecognizer(target: self,
action: #selector(handleTap(recognizer:)))
tapGesture.delegate = self
containerView.isUserInteractionEnabled = true
containerView.addGestureRecognizer(tapGesture)
}
@objc func handleTap(recognizer:UITapGestureRecognizer) {
//Call Delegate method from here...
}
}
2. In ViewController
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier",
for: indexPath) as! YourCell
cell.delegate = self
return cell
}
// MARK: Delegate
extension YourViewController : ViewTappedDelegate {
func viewTapped(_ photo : String) {
// Handle delegation here...
}
}
Upvotes: 3
Reputation: 3613
In order to add tap gesture please add the following code into the cell of your collection view.
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.socialViewTapped))
socialView?.addGestureRecognizer(tapGestureRecognizer)
socialView?.isUserInteractionEnabled = true
Add this code to the collection view cell.
Upvotes: 0