I have a simple app with a CollectionView
and items in it.
On long pressing a cell
a popup UIView
appears with a TextField
and an option to save it in the array
corresponding to the cell
.
Here is the code (The buttons
and gestures
have been added correctly in viewDidLoad()
method):
class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var longPressedPoint: CGPoint?
public var rowOfLongPressedItem: Int? = nil
func handleLongPress(longPressRecognizer: UILongPressGestureRecognizer) -> Int {
print("LONG PRESS Gesture Recognized")
notePopup.hidden = false
longPressedPoint = longPressRecognizer.locationInView(longPressRecognizer.view)
var indexPathOfLongPressedCell = self.itemCollectionView.indexPathForItemAtPoint(longPressedPoint!)
rowOfLongPressedItem = (indexPathOfLongPressedCell?.row)
print("rowOfLongPressedItem -> .\(rowOfLongPressedItem)")
return rowOfLongPressedItem!
}
func saveNoteButtonTapped(rowOfLongPressedItem: Int) {
print("rowOfLongPressedItem when Save button is tapped -> .\(rowOfLongPressedItem)")
//Can’t go further down as rowOfLongPressedItem is NOT available from “handleLongPress” function…
var selectedItem = ItemsList[rowOfLongPressedItem]
selectedItem.counts += 1
var latest = selectedItem.counts - 1
selectedItem.timestamp.append(NSDate())
selectedItem.note.append(noteTextField.text)
ItemsList[rowOfLongPressedItem] = selectedItem
print(".\(selectedItem.title) has been tapped .\(selectedItem.counts)")
print("The latest tap on .\(selectedItem.title) is at .\(selectedItem.timestamp[latest])")
print("The note .\(noteTextField.text) has been added")
notePopup.hidden = true
}
}
Tried solving the issue in couple of ways:
Defining a variable in the View Controller hoping that the function will return the value and save it in global variable. But, later found from Apple that "A function cannot have a higher access level than its parameter types and return type, because the function could be used in situations where its constituent types are not available to the surrounding code." https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html
I tried putting the Button's Selector function code inside the Long Press Gesture Function so that it's return value is easily available. But, I am unable to call the Selector function as it is inside another function.
Also, I tried returning the value of Long Press Gesture Function and using it in IBAction of the Save button. However, for this I need call handleLongPress
again and then the longPressedPoint
is detected as inside Save button. Hence, the indexPathOfLongPressedCell
is nil
and the app crashes.
Can someone please help me...
Assuming that you want to get the selected cell's row and assigns it to a global variable rowOfLongPressedItem
, you don't need to let handleLongPress
returns an Int.
NOTE: This is a Swift 3 code (with the same concept):
public var rowOfLongPressedItem: Int? = nil
override func viewDidLoad() {
//...
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.assignRowOfLongPressedItem))
itemCollectionView.addGestureRecognizer(longPressRecognizer)
//...
}
func assignRowOfLongPressedItem(longPressRecognizer: UILongPressGestureRecognizer) {
let longPressedPoint = longPressRecognizer.location(in: longPressRecognizer.view)
var indexPathOfLongPressedCell = self.itemCollectionView.indexPathForItem(at: longPressedPoint)
rowOfLongPressedItem = (indexPathOfLongPressedCell?.row)
// if you long press the first row -for example-, the output should be: "rowOfLongPressedItem -> .Optional(0)"
print("rowOfLongPressedItem -> .\(rowOfLongPressedItem)")
}
Also, you don't need to let saveNoteButtonTapped
to take rowOfLongPressedItem
parameter. Note that rowOfLongPressedItem
is optional, you should make sure it is not still nil (you can use Early Exit approach):
func saveNoteButtonTapped(sender: UIButton) {
guard let selectedCellRow = rowOfLongPressedItem else {
print("rowOfLongPressedItem is nil!!")
return
}
print("rowOfLongPressedItem when Save button is tapped -> .\(selectedCellRow)")
var selectedItem = ItemsList[selectedCellRow]
selectedItem.counts += 1
var latest = selectedItem.counts - 1
selectedItem.timestamp.append(NSDate())
selectedItem.note.append(noteTextField.text)
ItemsList[row] = selectedItem
print(".\(selectedItem.title) has been tapped .\(selectedItem.counts)")
print("The latest tap on .\(selectedItem.title) is at .\(selectedItem.timestamp[latest])")
print("The note .\(noteTextField.text) has been added")
notePopup.hidden = true
}