【问题标题】:Passing a variable from Gesture Recognizer function to an IBAction将变量从手势识别器函数传递到 IBAction
【发布时间】:2016-10-04 07:08:54
【问题描述】:

我有一个简单的应用程序,其中包含 CollectionView 和项目。 长按cell 时,弹出UIView 会出现TextField 和将其保存在与cell 对应的array 中的选项。

这是代码(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
}
}

尝试通过几种方式解决问题:

  • 在视图控制器中定义一个变量,希望该函数将返回值并将其保存在全局变量中。 但是,后来从苹果那里发现 “一个函数的访问级别不能高于其参数类型和返回类型,因为该函数可用于其组成类型对周围代码不可用的情况。” https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html

  • 我尝试将按钮的选择器功能代码放入长按手势功能中,以便轻松获得它的返回值。但是,我无法调用 Selector 函数,因为它位于另一个函数中。

  • 另外,我尝试返回长按手势功能的值并在保存按钮的 IBAction 中使用它。但是,为此我需要再次调用handleLongPress,然后将longPressedPoint 检测为内部保存按钮。因此,indexPathOfLongPressedCellnil,应用程序崩溃。

谁能帮帮我...

【问题讨论】:

    标签: swift uicollectionview uigesturerecognizer return-type ibaction


    【解决方案1】:

    假设您要获取所选单元格的行并将其分配给全局变量rowOfLongPressedItem,则无需让handleLongPress 返回一个Int。

    注意:这是一个 Swift 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)")
    }
    

    另外,你不需要让saveNoteButtonTappedrowOfLongPressedItem 参数。注意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
    }
    

    【讨论】:

    • 这样更好。它就像一个魅力。非常感谢!
    • 感谢您提醒我确保 rowOfLongPressedItem 不是 nil
    • 虽然这段代码有效,但我试图理解它为什么有效。基于“一个函数不能具有比其参数类型和返回类型更高的访问级别,因为该函数可以在其组成类型对周围代码不可用的情况下使用。” developer.apple.com/library/content/documentation/Swift/… 这个代码不应该工作,不是吗。 assignRowOfLongPressedItem如何保存rowOfLongPressedItem是全局变量?
    • @Ahmad 看来你错过了这个 -> ItemsList[row] = selectedItem ;)
    【解决方案2】:

    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
    }
    

    【讨论】:

    • 感谢您的回复。我不确定rowOfLongPressedItem。这是我现有代码rowOfLongPressedItem -> .Optional(2) rowOfLongPressedItem when Save button is tapped -> .140667464596544 fatal error: Array index out of range (lldb) 的输出另外,我尝试添加保护语句,但出现此错误“Initializer for conditional binding must have Optional type, not 'Int' 请帮助
    • 请忽略我之前的评论。我没有删除saveNoteButtonTapped() 函数中的参数但是,这里的一个小变化是:func saveNoteButtonTapped(sender: UIButton) 我已经做了这个更改并将您的回复标记为答案。非常感谢您的帮助。
    • @EcoApps 不客气:) 为什么需要 sender 参数?你没有在函数的任何地方使用它
    • @EcoApps 这是一个 IBAction 函数吗?
    • 不,是UIButton的选择器功能
    猜你喜欢
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多