Мне нужно было делегировать действие щелчка для моего UIView
класса моему UIViewController
классу. Поэтому я хотел, чтобы при нажатии кнопки в моем подвиде вызывалась функция в моем классе BrowserViewController.
Я использую protocol
для достижения этой цели, но я обнаружил, что мой delegate
возвращает nil
. Я не знаю, что делаю не так. Я застрял на этом уже несколько недель.
BrowseViewController
class BrowseViewController: UIViewController {
// Content container
lazy var container: UIStackView = {
let contentView = UIStackView(frame: .zero)
contentView.axis = .vertical
contentView.spacing = 10
contentView.willSetConstraints()
return contentView
}()
var explore: Explore! = Explore()// Explore section
var categoryItem: CategoryItem! = CategoryItem() //Category Item
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController!.navigationBar.isHidden = true
self.setupInterface()
}
// MARK: SETUP
private func setupInterface() {
self.embedInScrollView(content: self.container)
self.setupSearch() // Search
self.setupExplore() // Explore
DispatchQueue.main.async {
self.container.setBackground(color: UIColor.constants.lightGray)
}
}
// MARK: SEARCH HEADER
private func setupSearch() {
self.searchHeader = SearchHeader(frame: .zero)
self.searchHeader.willSetConstraints()
self.container.addArrangedSubview(self.searchHeader)
let constraints = [
self.searchHeader.topAnchor.constraint(equalTo: self.container.topAnchor),
self.searchHeader.heightAnchor.constraint(equalToConstant: 156),
self.searchHeader.widthAnchor.constraint(equalTo: self.view.widthAnchor),
// self.searchHeader.centerXAnchor.constraint(equalTo: self.container.centerXAnchor)
]
NSLayoutConstraint.activate(constraints)
DispatchQueue.main.async {
self.searchHeader.backgroundColor = UIColor(patternImage: UIImage(named: "header_background")!.resize(to: CGSize(width: self.searchHeader.bounds.width, height: self.searchHeader.bounds.height)))
self.searchHeader.setGradientBackground(gradientTop: UIColor.constants.darkBlue.withAlphaComponent(0.9).cgColor, gradientBottom: UIColor.constants.darkBlue.cgColor, opacity: 0.9)
self.searchHeader.applyConstraints()
}
}
// MARK: EXPLORE COMPONENT
private func setupExplore() {
self.categoryItem.isUserInteractionEnabled = true
self.categoryItem.delegate = self
self.container.addArrangedSubview(self.explore)
self.explore.willSetConstraints()
DispatchQueue.main.async {
NSLayoutConstraint.activate([
self.explore.leftAnchor.constraint(equalTo: self.view.leftAnchor),
self.explore.rightAnchor.constraint(equalTo: self.view.rightAnchor),
self.explore.heightAnchor.constraint(equalToConstant: 240),
])
self.explore.configure()
self.setupDailyPicks()
}
}
// MARK: DAILY PICKS
func setupDailyPicks() {
self.dailyPicks.delegate = self
self.container.addArrangedSubview(self.dailyPicks)
self.dailyPicks.willSetConstraints()
NSLayoutConstraint.activate([
self.dailyPicks.heightAnchor.constraint(equalToConstant: 297),
self.dailyPicks.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
self.dailyPicks.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
])
self.dailyPicks.load()
self.container.setNeedsDisplay()
self.container.setNeedsLayout()
self.setupFreshFinds()
}
extension BrowseViewController: ExploreDelegate {
func categoryClicked(category: ProductCategory) {
let categoryView = ProductByCategoryView()
categoryView.category = category
categoryView.modalPresentationStyle = .overCurrentContext
self.navigationController?.pushViewController(categoryView, animated: true)
}
}
Explore.xib
protocol ExploreDelegate:UIViewController {
func categoryClicked(category: ProductCategory)
}
//enum Categories: String, CaseIterable {
//
//}
class Explore: UIView {
@IBOutlet weak var electronics: CategoryItem!
@IBOutlet weak var mobilePhones: CategoryItem!
@IBOutlet weak var travel: CategoryItem!
@IBOutlet weak var womenFashion: CategoryItem!
@IBOutlet weak var menFashion: CategoryItem!
@IBOutlet weak var health: CategoryItem!
@IBOutlet weak var arts: CategoryItem!
@IBOutlet weak var babies: CategoryItem!
@IBOutlet weak var rentals: CategoryItem!
@IBOutlet weak var realEstate: CategoryItem!
@IBOutlet weak var agriculture: CategoryItem!
@IBOutlet weak var jobs: CategoryItem!
@IBOutlet weak var everything: CategoryItem!
var categoriesView: UIView!
var titleLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
func setup() {
self.titleLabel = UILabel(frame: CGRect(origin: .zero, size: CGSize(width: 133, height: 20)))
self.titleLabel.font = UIFont(name: "Hind", size: 18)?.bold
self.titleLabel.text = "Explore Kusnap"
self.titleLabel.willSetConstraints()
self.addSubview(self.titleLabel)
// Container for categories
let categoriesContainer = UIScrollView()
categoriesContainer.isScrollEnabled = true
categoriesContainer.willSetConstraints()
self.categoriesView = loadViewFromNib()
self.categoriesView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: self.bounds.width, height: 186))
self.categoriesView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
categoriesContainer.addSubview(self.categoriesView)
self.categoriesView.willSetConstraints()
self.addSubview(categoriesContainer)
NSLayoutConstraint.activate([
self.titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 14),
self.titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 14),
categoriesContainer.heightAnchor.constraint(equalToConstant: 186),
categoriesContainer.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -14),
categoriesContainer.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 14),
categoriesContainer.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 14),
self.categoriesView.topAnchor.constraint(equalTo: categoriesContainer.topAnchor),
self.categoriesView.bottomAnchor.constraint(equalTo: categoriesContainer.bottomAnchor),
self.categoriesView.leftAnchor.constraint(equalTo: categoriesContainer.leftAnchor),
self.categoriesView.rightAnchor.constraint(equalTo: categoriesContainer.rightAnchor),
])
}
func configure() {
let categoryButtons = [electronics, mobilePhones, travel, womenFashion, menFashion, health, arts, babies, rentals, realEstate, agriculture, jobs, everything]
let categories: [ProductCategory] = ProductCategory.allCases
categoryButtons.enumerated().forEach({
$0.element?.category = categories[$0.offset]
})
self.layoutIfNeeded()
}
}
class CategoryItem: UIView {
weak 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) {
print(self.delegate!) //returns nil
self.delegate?.categoryClicked(category: ProductCategory.arts)
self.tapped?(self.category)
}
}