Search code examples
swiftuikit

how to work with initializers inside UIView?


Good afternoon everyone. Guys, tell me how it is possible to initialize a custom parameter in view? I want to pass the variable currentMenuItem inside the SampleSkinsCollectionView class. I just can’t understand how the initializer works inside IUView.

This parent View. I add class "SampleSkinsCollectionView".

final class MainSecondViewController: HeaderMenuViewController {

    // MARK: - Dependencies
    var iterator: IMainIterator?
    var handlerCardCellDelegate: IHandlerCellDelegate?

    // MARK: - Private properties
    private var currentMenuItem: MenuItem?
    private lazy var collectionCardSkins = SampleSkinsCollectionView()

    override init(delegate: IMenuDelegate, currentMenuItem: MenuItem) {
        super.init(delegate: delegate, currentMenuItem: currentMenuItem)
        self.currentMenuItem = currentMenuItem
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Public methods
    override func viewDidLoad() {
        super.viewDidLoad()
        setupConfiguration()
        addUIView()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        setupLayout()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(true, animated: false)
    }
}

private extension MainSecondViewController {
    func setupConfiguration() {
        collectionCardSkins.translatesAutoresizingMaskIntoConstraints = false
        collectionCardSkins.handlerCellDelegate = self
    }
}

This is childred UIView. I don`t can to initialize field "currentMenuItem" Xcode show two error:

  • 'self' used in property access 'frame' before 'super.init' call
  • Property 'self.currentMenuItem' not initialized at super.init call
import UIKit

final class SampleSkinsCollectionView: UIView {

    // MARK: - Dependencies
    var handlerCellDelegate: IHandlerCellDelegate?
    var currentMenuItem: MenuItem

    // MARK: - Private properties
    private lazy var collectionCardMaps = createCollectionView()

    private var modelForDisplay: [SkinsModel] = []

    // MARK: - Initializator

    init(currentMenuItem: MenuItem) {
        super.init(frame: frame)
        self.currentMenuItem = currentMenuItem
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        addUIView()
        setupConfiguration()
        setupLayout()
    }

    convenience init(handlerCellDelegate: IHandlerCellDelegate?) {
        self.init(frame: CGRect.zero)
        self.handlerCellDelegate = handlerCellDelegate
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Public methods
    func reloadModel(viewModel: [SkinsModel]) {
        self.modelForDisplay = viewModel
        collectionCardMaps.reloadData()
    }
}

Solution

  • the properties of subclass must be initialized before superclass. It will look like this:

    final class SampleSkinsCollectionView: UIView {
    
    // MARK: - Dependencies
    var currentMenuItem: MenuItem
    
    // MARK: - Initializator
    init(currentMenuItem: MenuItem) {
        self.currentMenuItem = currentMenuItem
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    

    }

    you can read more about initialization in Swift documentation