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.")
}
}
}
}
}
Related
Currently, I have a collection view with a UILongPressGestureRecognizer on the cell in cellForItemAt:
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressOnCell))
cell.addGestureRecognizer(longPress)
When the user holds down on a cell, it triggers a function to show a menu called cellDeleteAppear(). However, after the menu is on the screen, the user can then hold down on another cell which will cause the menu to pop up again.
#objc func handleLongPressOnCell(_ sender: UILongPressGestureRecognizer) {
if sender.state == .began {
cellDeleteAppear()
let gestureLocation = sender.location(in: self.trayCollectionView)
if let indexPath = self.trayCollectionView.indexPathForItem(at: gestureLocation) {
indexPathForDeletion = indexPath
trayCollectionView.allowsSelection = false
} else {
print("long press error at index path")
}
}
}
My goal is: while the menu is active, the user should not be able to hold down on another cell to trigger the menu to pop up. Any help is appreciated!
Then do
var menuShown = false
#objc func handleLongPressOnCell(_ sender: UILongPressGestureRecognizer) {
if sender.state == .began {
guard !menuShown else { return }
menuShown = true
And when you hide it do
menuShown = false
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.
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.
I have a UITableView in ViewController and 3 UILabel in it with a Prototype Cell labeled Date, Party and Amount. Now situation is that i want whenever a user tapped on a UILabel, say Date, it shows all records from Database table for particular Date or if User tapped on Party Label then All transactions of particular party will be shown. So please help me in getting this. How could i do this..
There are many to do the same.
You can use button without any border or background image. Just give simple text to button and it would look like label. Add action to the button.
You can use UIGestureRecognizers for the same. You can add Gesture Recognizer directly to all UILabel separately as explained by #LalitKumar. .
You can also add Gesture Recognizer to your Table View and access all its subviews in your UIGesture Recognizer Action .
Add Gesture Recognizer in viewDidLoad as
let tap = UITapGestureRecognizer(target: self, action: #selector(Yourcontroller.handleTap))
yourTableView.isUserInteractionEnabled = true
yourTableView.addGestureRecognizer(tap)
Define action for Gesture Recognizer and get indexpath of cell as well as subviews of cell.
func handleTap(_ gesture: UITapGestureRecognizer){
let tapLocation = gesture.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation)
{
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) as? UITableViewCell
{
print("Row Selected") // access tapped cell and its subview as
let touchpoint:CGPoint = gesture.location(in: cell)
if cell.datelabel.frame.contains(touchpoint) {
// user tapped date label
} elseif cell.imageView.frame.contains(touchpoint) {
// user tapped image
}
}
}
}
let tap = UITapGestureRecognizer(target: self, action: #selector(Yourcontroller.tapLabelFunction))
yourLabel.isUserInteractionEnabled = true
yourLabel.addGestureRecognizer(tap)
// if you make label on the cell
cell.yourLabel.userInteractionEnabled = true
cell.yourLabel.tag = indexPath.row
cell.yourLabel.addGestureRecognizer(tap)
}
func tapLabelFunction(sender:UITapGestureRecognizer) {
print("label tapped",sender.view!.tag); // for tag
}
Add this in cellForRowAtIndexPath
yourLabel?.isUserInteractionEnabled = true
if ((yourLabel?.gestureRecognizers?.description) == nil) {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tap(onPeopleName:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
tapGesture.cancelsTouchesInView = false
yourLabel?.addGestureRecognizer(tapGesture)
}
Selector
func tap(onPeopleName gesture: UIGestureRecognizer) {
let lbl: UILabel? = (gesture.view as? UILabel)
let cell: UITableViewCell? = (lbl?.superview?.superview as? UITableViewCell)
let indexPath: IndexPath? = tblViewPracticeDetail.indexPath(for: cell!)
}
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