【问题标题】:Custom delegate method not being called when returning to app from background从后台返回应用程序时未调用自定义委托方法
【发布时间】:2017-11-20 15:06:11
【问题描述】:

我一直在开发一个需要在 UITableViewCell 中放置 UICollectionView 的应用程序。每个 UICollectionViewCell 都有两个按钮,我需要在 TableViewController 类中处理它们。因此,当我从那里设置每个 CollectionViewCell 时,我向这些按钮添加了目标以调用 TableViewCell 类中的方法。然后,我有一个从该方法调用的自定义委托方法,并且我已经在我的 TableViewController 类中实现了该方法。除非我按下设备上的主页按钮然后返回应用程序,否则一切都按预期工作。 TableViewCell 类中的方法仍在调用,但不是我的 TableViewController 类中的方法。

这是我的协议和处理程序

protocol CollectionViewCellButtonPressHandlerDelegate {
    func handle(button: UIButton?, data: Any?)
}

class CollectionViewCellButtonPressHandler {
    var delegate: CollectionViewCellButtonPressHandlerDelegate?

    func handle(button: UIButton?, data: Any?) {
        if self.delegate != nil {
            delegate?.handle(button: button, data: data)
        }
    }
}

除了设置 TableViewCell,这是我的 TableViewController 的 cellForRowAtIndexPath 方法中的代码

cell.handler = CollectionViewCellButtonPressHandler()
cell.handler.delegate = self
cell.goalCollectionView.reloadData()

这是我在 TableViewController 类中的委托方法的实现。

func handle(button: UIButton?, data: Any?) {
        if let msg = data as? String {
            print(msg)
        }
}

这就是我在 TableViewCell 类的 cellForRowAtIndexPath 方法中将目标设置为按钮的方式

cell.playButton.addTarget(self, action: #selector(self.play(sender:)), for: .touchUpInside)

这是我的 TableViewCell 类中播放按钮动作的实现

func play(sender: UIButton) {
        for i in 0..<goals.count {
            let indexPath = IndexPath(row: i, section: 0)
            if let cell = self.goalCollectionView.cellForItem(at: indexPath) as? GoalCollectionViewCell {
                if sender == cell.playButton {
                    print("Play: ", self.goals[indexPath.row].subskill!)
                    self.handler.handle(button: sender, data: self.goals[indexPath.row])
                }
            }
        }
    }

委托方法上面的打印语句即使在从后台返回后也会执行,但下一条语句不会。我还检查了处理程序及其代表是否为零,但它们不是。请帮忙。

【问题讨论】:

  • 哪一个符合协议(CollectionViewCellButtonPressHandlerDelegate)? UITableViewCOntroller 还是 UITableViewCell?
  • TableViewController 因为这是我需要处理按钮按下的地方。
  • CollectionViewCellButtonPressHandler 中的handle 函数是否是一个随机函数,与您的委托函数func handle(button: UIButton?, data: Any?) 具有相同的名称和结构?
  • 没有。 CollectionViewCellButtonPressHandler 类是用于在委托类中使用适当的参数调用句柄方法的类,在这种情况下,它恰好是我的 TableViewController 类。您可以在我的 TableViewController 类的 cellForRowAtIndexPath 方法中看到该类的运行情况。
  • 好吧,我为您的情况提供了另一种解决方案,您可以找到它作为答案。我希望它有所帮助。

标签: ios swift uitableview swift3 uicollectionview


【解决方案1】:

Swift 3: 用于将(collectionView 或 tableView)单元格中的按钮的操作传递给控制器​​,如您所知,您必须使用委托。如果此按钮位于另一个(collectionView 或 tableView)单元格中的单元格中,则您需要多一个委托。你必须在这个层次结构中传递数据。 您可以使用此示例代码将按钮操作和数据从collectionViewCell 传递给tableViewCell,然后再传递给ViewController

我检查了这个,它总是可以工作,即使应用程序先移到后台再移到前台。

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, TableViewCellPassPressActionToControllerDelegate {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tableView.delegate = self
        tableView.dataSource = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
        cell.delegate = self
        return cell
    }

    func passAction(button: UIButton?, data: Any?) {
        //you have the click of the button in collectionviewcell here
    }

}

class TableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, CollectionViewCellButtonPressHandlerDelegate {

    @IBOutlet weak var collectionView: UICollectionView!

    var delegate: TableViewCellPassPressActionToControllerDelegate?

    override func awakeFromNib() {
        collectionView.delegate = self
        collectionView.dataSource = self
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
        cell.delegate = self
        return cell
    }

    func handle(button: UIButton?, data: Any?) {
        delegate?.passAction(button: button, data: data)
    }
}

class CollectionViewCell: UICollectionViewCell {
    var delegate: CollectionViewCellButtonPressHandlerDelegate?

    @IBAction func press(_ sender: UIButton) {
        delegate?.handle(button: sender, data: nil/*any data*/)
    }
}

protocol CollectionViewCellButtonPressHandlerDelegate {
    func handle(button: UIButton?, data: Any?)
}

protocol TableViewCellPassPressActionToControllerDelegate {
    func passAction(button: UIButton?, data: Any?)
}

【讨论】:

  • 感谢您的帮助,但即使使用您指定的方法,我的问题仍未解决。从后台返回应用程序后,我可以在 TableViewCell 的句柄方法中获取日志,但不能在 TableViewController 中获取日志。在按下主页按钮之前,按钮工作正常。
猜你喜欢
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
相关资源
最近更新 更多