Делегирование действий через протокол не работает быстро - PullRequest
0 голосов
/ 02 мая 2020

Мне нужно было делегировать действие click для моего 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)
    }
  }
}

Ответы [ 3 ]

1 голос
/ 05 мая 2020

Просто добавьте оператор печати внутри categoryTapped.

Затем вы узнаете, действительно ли он прослушивается.

Миллион вещей может go ошибиться, для Например, вы можете забыть установить 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")
  ....

Посмотрите, что произойдет.

0 голосов
/ 05 мая 2020

Есть несколько вещей, которые могут привести к тому, что метод делегата не будет запущен в этом коде:

  1. Убедитесь, что isUserInteractionEnabled = true на вашем CategoryItem. Это, вероятно, лучше всего сделать в функции configure() в CategoryItem или в функции setupExplore() BrowseViewController.
  2. Убедитесь, что функция setupExplore() на BrowseViewController вызывается, и category устанавливается на CategoryItem для запуска функции configure. В противном случае, возможно, не установлен ни делегат, ни распознаватель жестов.

Примечание для стороны - weak против strong делегат

В примечании для стороны обычно рекомендуется чтобы сделать ваши свойства делегата weak var, а не использовать их как надежную ссылку, поскольку это делает их склонными к сильным циклам сохранения

Таким образом, вы можете рассмотреть возможность преобразования var delegate: ExploreDelegate? на вашем CategoryItem в weak var delegate: ExploreDelegate?. Для получения дополнительной информации об этой проблеме, просмотрите это сообщение .

0 голосов
/ 02 мая 2020

Я не вижу ни одного фрагмента кода, который устанавливает delegate.

Прежде всего, определите delegate как свойство внутри CategoryItem класса, затем вы должны установить текущий экземпляр BrowseViewController до delegate переменной CategoryItem. Теперь вы можете ожидать вызова вашего метода.

...