0

我有一個簡單的應用程序,其中包含CollectionView及其中的項目。 長按cell彈出UIView出現一個TextField和一個選項將其保存在對應於cellarray將手勢識別器功能中的變量傳遞給IBAction

這裏是代碼(buttonsgestures已經在viewDidLoad()方法正確添加):

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 
} 
} 

試圖解決的問題在幾個方面:

  • 在定義一個變量View Controller希望函數返回值並將其保存在全局變量中。 但是,後來從Apple發現, 「函數不能具有比其參數類型和返回類型更高的訪問級別,因爲該函數可用於其構成類型不可用於周圍代碼的情況。」 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html

  • 我試圖把按鈕的選擇功能碼長按手勢功能的內部,使得它的返回值是容易獲得的。但是,我無法調用Selector函數,因爲它在另一個函數中。

  • 此外,我試着返回長按手勢功能的值,並在保存按鈕的IBAction中使用它。但是,爲此,我需要再次調用handleLongPress,然後longPressedPoint被檢測爲保存按鈕內部。因此,​​是nil和應用程序崩潰。

有人可以幫我...

回答

2

假設你想獲得所選單元格的行,並將其分配給全局變量rowOfLongPressedItem,你不需要讓handleLongPress返回一個int。

注意:這是一個斯威夫特3碼(具有相同的概念):

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)") 
} 

而且,你不需要讓saveNoteButtonTapped採取rowOfLongPressedItem參數。需要注意的是rowOfLongPressedItem是可選的,你應該確保它不是仍然爲零(你可以使用Early Exit方法):

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 
} 
+0

這更好。它像一個魅力。非常感謝! –

+1

謝謝你提醒我確保'rowOfLongPressedItem'不是'nil'。 –

+0

儘管這段代碼有效,但我試圖理解它爲什麼起作用。 基於「函數不能具有比其參數類型和返回類型更高的訪問級別,因爲該函數可用於其構成類型不可用於周圍代碼的情況。」 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html 這段代碼不應該工作,不是嗎。 'assignRowOfLongPressedItem'如何保存作爲全局變量的'rowOfLongPressedItem'? –

0

rowOfLongPressedItem可用於兩種功能。您無需將其設置爲saveNoteButtonTapped的參數。

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() { 

    guard let row = rowOfLongPressedItem else { 
     return // rowOfLongPressedItem was nil 
    } 

    print("rowOfLongPressedItem when Save button is tapped -> .\(row)") 
    var selectedItem = ItemsList[row] 

    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 
} 
+0

謝謝您的答覆。我不知道如果'rowOfLongPressedItem'。這裏是我現有代碼的輸出 'rowOfLongPressedItem - > .Optional(2) rowOfLongPressedItem當點擊保存按鈕時 - >。140667464596544 致命錯誤:數組索引的範圍 (LLDB)' 另外,我嘗試添加保護聲明,但得到這個錯誤」 '初始值設定條件結合必須有可選的類型,而不是「Int'' 請幫助 –

+0

請忽略我以前的評論我沒有刪除'saveNoteButtonTapped()'函數中的參數 但是,這裏的一個小改變是: 'func saveNoteButtonTapped(sender:UIButton)' 我做了這個改變並標記了你的回覆作爲回答 非常感謝您的幫助 –

+0

@EcoApps不客氣:)爲什麼你需要sender參數?你在功能的任何地方都沒有使用它 –