UICollectionView with gesture recogniser - ios

I have a UICollectionView which has a long press gesture attached to it. It works fine when i'm pressing on a cell but if the touched area isn't a cell the app crashes with EXC_BREAKPOINT
It crashes on the
if let indexPath : NSIndexPath = collectView.indexPathForItemAtPoint(point)! {
line. I believe that i need to check that the point is actually a cell but i'm not sure what to check for
the code is as follows
#IBAction func longPressCell(sender: UILongPressGestureRecognizer) {
if (sender.state == UIGestureRecognizerState.Began) {
if let point : CGPoint = sender.locationInView(self.collectionView) {
if let collectView = self.collectionView {
if let indexPath : NSIndexPath = collectView.indexPathForItemAtPoint(point)! {
let adopt : UserPet = self.fetchedResultsController.objectAtIndexPath(indexPath) as! UserPet
NSLog("Adopt: \(adopt)")
}
}
}
}
}

collectView.indexPathForItemAtPoint(point) != nil {
Solved it

Related

how show user selected cell of tableview on longpress

Hello i am adding UILongPressGesture in my tableview and i have added successfully but issue is that how to show that cell is selected i mean i want change color of selected cell and when i again do longpress on selected cell than i want to delselect cell
i have try to add long press in my tableview with code and assign delegates on LongPress here is my code
#objc func longPress(_ longPressGestureRecognizer: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == UIGestureRecognizer.State.began {
let touchPoint = longPressGestureRecognizer.location(in: self.tblList)
if let indexPath = tblList.indexPathForRow(at: touchPoint) {
}
}
}
And in viewDidload() i am writing this code
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(SMSChatViewController.longPress(_:)))
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.delegate = self
self.tblList.addGestureRecognizer(longPressGesture)
so from this code i am able to select cell but how to show user that the cell is selected i don't know how to do this
so i just want like that when user is do longpress than cell color change and set as selected and then again do longpress than deselect cell with its original color
What about you change just the backgroundColor of the cell, when the longPressGesture is recognized? Something like this:
#objc func longPress(_ longPressGestureRecognizer: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == UIGestureRecognizer.State.began {
let touchPoint = longPressGestureRecognizer.location(in: self.tblList)
if let indexPath = tblList.indexPathForRow(at: touchPoint) {
let cell = tblList.cellForRow(at: indexPath)
if (cell.isSelected) {
cell.backgroundColor = UIColor.clear // or whatever color you need as default
cell.setSelected(false, animated: true)
} else {
cell.backgroundColor = UIColor.orange
cell.setSelected(true, animated: true)
}
}
}
}
If you need clarification or i missunderstood a thing let me know and i will edit my answer.

Using tap gesture and long press at the same time in Table View

I'm building a table view and I cannot seem to get both regular taps and long presses to work.
I have placed this code in my viewDidLoad:
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
myTableView.addGestureRecognizer(longPress)
and this code is my gesture recognizer:
#objc func handleLongPress(sender: UILongPressGestureRecognizer){
if UILongPressGestureRecognizer.state == UIGestureRecognizer.State.began {
let touchPoint = UILongPressGestureRecognizer.location(in: self.myTableView)
if let indexPath = self.myTableView.indexPathForRowAtPoint(touchPoint) {
print(indexPath.row)
}
}
}
I have found this code here on Stack Overflow, but I do not think it is up to date for Swift 4 because I can not even run it without the build failing.
UILongPressGestureRecognizer.state should be sender.state and UILongPressGesutreRecognizer.location should be sender.location. Also, the signature for indexPathForRowAtPoint() has been updated to indexPathForRow(at:).
Corrrected code:
#objc func handleLongPress(sender: UILongPressGestureRecognizer) {
if sender.state == .began {
let touchPoint = sender.location(in: self.myTableView)
if let indexPath = self.myTableView.indexPathForRow(at:touchPoint) {
print(indexPath.row)
}
}
}
UILongPressGestureRecognizer is a class name, you need to be calling the class instance.

Transform TableView Tap Location to Cell View Location

I have a TapGestureRecognizer on my TableView.
It get me the cell I tapped on.
Next I want to use the tapped location to check if a Label on the cell was tapped.
But of course I have the location relative to the TableView and not to the CellView.
Do you know a convenient way to transform a TableView Location ("World") to the corresponding CellView Location ("Local")?
Thank you very much.
My code so far.
viewDidLoad:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyTableViewController.tapEdit(recognizer:)))
self.tableView.addGestureRecognizer(tapGesture)
tapGesture.delegate = self
Tap Method:
#objc func tapEdit(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.ended {
let tapLocation = recognizer.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
print("Tap Location: \(tapLocation)")
if let cell = self.tableView.cellForRow(at: tapIndexPath) as? MyTableViewCell {
// of course not working because of the relative location difference
if cell.myLabel.frame.contains(tapLocation) {
print("Taped cell at \(tapIndexPath). Hit Label.")
}
}
}
}
}
Regards
The simplest way if you want to have the local coordinate of that cell, you should use it to get the location of that tap:
#objc func tapEdit(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.ended {
let tapLocation = recognizer.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
print("Tap Location: \(tapLocation)")
if let cell = self.tableView.cellForRow(at: tapIndexPath) as? MyTableViewCell {
let localLocation = recogniser.location(in: cell)
// of course not working because of the relative location difference
if cell.myLabel.frame.contains(localLocation) {
print("Taped cell at \(tapIndexPath). Hit Label.")
}
}
}
}
}

How to get the indexpath.row when a UIImageView in a cell is tapped?

swift: how to get the indexpath.row when a button in a cell is tapped?
This link is an answer for when a button is tapped, and if my question is not possible I'll just use a button and put the image on it. I was just wondering if it is possible to this with tapping a UIImageView instead of a button. I tried the exact answer with a UIImageView instead of a UIButton and I got this error
"fatal error: unexpectedly found nil while unwrapping an Optional value".
cell.imagePosted is a UIImageView
let tapGR = UITapGestureRecognizer(target: self,action:Selector("imageTapped:"))
cell.imagePosted.userInteractionEnabled = true
cell.imagePosted.addGestureRecognizer(tapGR);
func imageTapped(img: AnyObject)
{
if let imgView = img as? UIImageView {
if let superView = imgView.superview {
if let cell = superView.superview as? CellCustom {
indexPath2 = self.tableView.indexPathForCell(cell)
}
}
}
print(indexPath2.row)
}
this might help you,
add an UITapGestureRecognizer to UIImageView
You can store indexpath.row in tag property of UIImageView and access that tag on UITapGestureRecognizer event
for example (Objective-C) :
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleImageTap:)];
tap.cancelsTouchesInView = YES;
tap.numberOfTapsRequired = 1;
[cell.imageView addGestureRecognizer:tap];
cell.imageView.tag = indexPath.row;
and get indexpath.row
-(void)handleImageTap:(UITapGestureRecognizer *)gestureRecognizer{
UIView* view = gestureRecognizer.view;
CGPoint loc = [gestureRecognizer locationInView:view];
NSInteger indexpath = [view hitTest:loc withEvent:nil].tag;
NSLog(#"%ld",(long)indexpath);
}
You can create a protocol with a method like imageViewInCellTapped(cell:YourCellType)and a delegate property in the cell. In cellForRowAtIndexPath set the controller the delegate of each cell and implement the method from the protocol. When something happens in your cell like a button or image is tapped you can call delegate?.imageViewInCellTapped(self) where self is the cell then in your controller where this method is implemented you get the index using indexPathForCell method of the tableView.
Here is Madan's code in swift if anybody is interested:
func imageTapped(gestureRecognizer: UITapGestureRecognizer) {
var view: UIView!
var loc: CGPoint!
view = gestureRecognizer.view
loc = gestureRecognizer.locationInView(view)
var indexPath: NSInteger!
indexPath = (view.hitTest(loc, withEvent: nil)?.tag)!
print(indexPath)
}
Hope this code helps to get indexpath for tapped cell swift 3:
func nameTapped(_ sender:UITapGestureRecognizer)
{
var pointVAlue = CGPoint()
pointVAlue = sender.location(in: infoTable)
var indexPath = IndexPath()
indexPath = infoTable.indexPathForRow(at: pointVAlue)!
print(indexPath.row)
/* if indexPath != nil {
let userEnt = ratingArray.object(at: indexPath.row)as! RateEntity
let detailVc = AssociateDetailViewController()
if ((userEnt.userId as String).isEmpty == false )
{
detailVc.m_otherUserId = userEnt.userId as String
self.navController!.pushViewController(detailVc, animated: true)
}
}*/
}

adding UILongPressGestureRecognizer to last tableview cell fails to detect locationInView

I'm trying to add a UILongPressGestureRecongnizer to each tableview cell. The following code works in all cases except the last cell:
ViewDidLoad:
let longpress = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
longpress.minimumPressDuration = 0.35
tableView.addGestureRecognizer(longpress)
handleLongPress:
func handleLongPress(sender:UILongPressGestureRecognizer!) {
let localLongPress = sender as UILongPressGestureRecognizer
var locationInView = localLongPress.locationInView(tableView)
// returns nil in the case of last cell
// but strangely only on Ended State
var indexPath = tableView.indexPathForRowAtPoint(locationInView)
if indexPath != nil {
var cell = self.tableView.cellForRowAtIndexPath(indexPath!) as MyCellTableViewCell
println("Long press Block .................");
if (sender.state == UIGestureRecognizerState.Ended) {
println("Long press Ended");
} else if (sender.state == UIGestureRecognizerState.Began) {
println("Long press detected.");
}
}
}
In the case of my last cell, I always see the UIGestureRecognizerState.Began but I do not see the UIGestureRecognizerState.Ended. I see both states for every cell, except the last tableviewcell. tableview.indexPathForRowAtPoint() resolves to nil in this case. What am I doing wrong?

Resources