【问题标题】:Delegating action through protocol not working swift通过协议委派行动不迅速
【发布时间】:2020-08-16 15:01:18
【问题描述】:

我需要将我的UIView 类的单击操作委托给我的UIViewController 类,因为 Swift 不支持多类继承。所以我想要这样,一旦在我的子视图上单击一个按钮,我的 BrowserViewController 类中的一个函数就会被调用。

我正在使用protocol 来实现这一点,但是在点击按钮时不会触发该功能。请帮帮我。

视图控制器


class BrowseViewController: UIViewController {

  var categoryItem: CategoryItem! = CategoryItem() //Category Item

  private func setupExplore() {
    //assign delegate of category item to controller
    self.categoryItem.delegate = self
  }
}

// delegate function to be called
extension BrowseViewController: ExploreDelegate {
  func categoryClicked(category: ProductCategory) {
    print("clicked")
    let categoryView = ProductByCategoryView()
    categoryView.category = category
    categoryView.modalPresentationStyle = .overCurrentContext

    self.navigationController?.pushViewController(categoryView, animated: true)
  }
}

Explore.swift(子视图)

import UIKit

protocol ExploreDelegate: UIViewController {
  func categoryClicked(category: ProductCategory)
}

class Explore: UIView {
  var delegate: ExploreDelegate?

  class CategoryItem: UIView {
    var delegate: ExploreDelegate?
    var category: ProductCategory? {
      didSet {
        self.configure()
      }
    }

    var tapped: ((_ category: ProductCategory?) -> Void)?

    func configure() {
      self.layer.cornerRadius = 6
      self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.categoryTapped)))
      self.layoutIfNeeded()
    }

    @objc func categoryTapped(_ sender: UIGestureRecognizer) {
      delegate?.categoryClicked(category: ProductCategory.everything)
      self.tapped?(self.category)
    }
  }
}

【问题讨论】:

    标签: ios swift protocols


    【解决方案1】:

    只需在 categoryTapped 中添加一个打印语句

    然后你就会知道它是否真的被窃听了。

    一百万件事可能会出错,例如,您可能忘记将 UIView 设置为允许交互。

    检查之后。 接下来在 categoryTapped 中添加另一个打印语句,它会显示delegate 变量是否为空。

    您将使用简单的打印语句快速发现问题。

    print("I got to here!")
    

    就这么简单。

    然后呢

    if delegate == nil { print("it is nil!! oh no!" }
    else { print("phew. it is NOT nil.") }
    

    在这个级别上调试真的很容易。

    接下来添加打印语句里面 setupExplore()

    func setupExplore() {
      print("setup explore was called")
      ....
    

    看看会发生什么。

    【讨论】:

    • 我的按钮点击事件效果很好,因为我已经使用打印语句进行了测试。问题是委托方法没有被调用。
    • hi @customapps - 添加一个打印语句,打印委托变量 - 你会看到它是否存在。很可能为零。
    • 你的意思是像:print(self.delegate!)
    • 嗨 @customapps - 当然,只需 print("try this!" + delegate) 就可以了,不需要 self。
    • 类似 " if delegate == nil { print("it is nil!! oh no!" } else { print("phew.it is NOT nil.") }
    【解决方案2】:

    我没有看到任何设置delegate 的代码。

    首先,将delegate定义为CategoryItem类内部的属性,然后必须将BrowseViewController的当前实例设置为CategoryItemdelegate变量。现在你可以期待你的方法被调用了。

    【讨论】:

    • 请查看我的代码。我已经进行了更改,但结果相同
    • 首先,将delegate属性定义为星期以避免内存泄漏问题weak var delegate: ExploreDelegate 。然后尝试在函数@objc func categoryTapped(_ sender: UIGestureRecognizer) 中打印出delegate,以确定delegate 是否有价值。
    • 我这样做了。它返回 null
    【解决方案3】:

    有几件事可能会导致在此代码中无法触发委托方法:

    1. 确保isUserInteractionEnabled = true 在您的CategoryItem 上。这可能最好在CategoryItem 中的configure() 函数或BrowseViewControllersetupExplore() 函数中完成。
    2. 确保正在调用BrowseViewController 上的setupExplore() 函数,并且正在CategoryItem 上设置category 以触发configure 函数。否则,可能未设置委托或手势识别器。

    旁注 - weakstrong 委托

    附带说明,通常最好的做法是让您的委托属性weak var 而不是让它们成为强引用,因为这会使它们容易出现强保留周期。

    因此,您可能需要考虑将CategoryItem 上的var delegate: ExploreDelegate? 设置为weak var delegate: ExploreDelegate?。有关此问题的更多信息,view this post

    【讨论】:

    • 代表仍然返回 nil
    • 在这种情况下,我需要更多信息。在您的问题中,您能否包括调用setupExplore() 的代码?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多