如何初始化委托给类?

问题描述 投票:0回答:1

大家下午好。 伙计们,告诉我如何将代理添加到菜单中?

我有一个使用委托的 MenuMainView 类。

protocol IChangeMenuItemHandler: AnyObject {
    func changeMenuItem() -> Void
}

我不添加委托来初始化。 XCode 显示错误属性“self.delegate”未在 super.init 调用时初始化

import UIKit

protocol IChangeMenuItemHandler: AnyObject {
    func changeMenuItem() -> Void
}

final class MenuMainView: UIView {

    // MARK: - Dependencies
    let fabricShadow = FabricShadows()

    // MARK: - Private properties
    private var menuItem: MenuItem!
    private let delegate: IMenuDelegate!
    private var handlerChangeMenuItemDelegate: IChangeMenuItemHandler?
    private let heightButton = GlobalSizes.Height.heighButton


    private lazy var gradient = createGradient()
    private lazy var viewDieShadow = createView()
    private lazy var viewDie = createView()
    private lazy var labelNameMenu = createLabel()
    private lazy var buttons: [UIButton] = []
    private lazy var vStack = createStack([])

    // MARK: - Initializator

    override init(frame: CGRect) {
        super.init(frame: frame)  // This is error: Property 'self.delegate' not initialized at super.init call
        addUIView()
        setupConfiguration()
        setupLayout()
    }

    convenience init(
            frame: CGRect,
            menuItems: MenuItem.Type,
            delegate: IMenuDelegate,
            handlerChangeMenuItemDelegate: IChangeMenuItemHandler?
    ) {
        self.init(frame: CGRect.zero)
        self.handlerChangeMenuItemDelegate = handlerChangeMenuItemDelegate
    }

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

// MARK: - UI Action.
private extension MenuMainView {
    @objc func showMapsScene(_ sender: UIButton) {
        let item = MenuItem.allMenuItems[sender.tag]
        handlerChangeMenuItemDelegate?.changeMenuItem()
    }
}

如何将委托 handlerChangeMenuItemDelegate 添加到类 Menu 中? 我有错误 - 在初始化之前使用了变量“self.menuView”

final class Menu {
    private let delegate: IMenuDelegate
    private let screenSize = UIScreen.main.bounds
    private(set) var menuView: MenuMainView
    var currentMenuItem: MenuItem = .maps
    var handlerChangeMenuItemDelegate: IChangeMenuItemHandler?

    internal init(delegate: any IMenuDelegate) {
        self.delegate = delegate
        self.menuView = MenuMainView(
            frame: screenSize,
            menuItems: MenuItem.self,
            delegate: delegate,
            handlerChangeMenuItemDelegate: self. // This is error: Variable 'self.menuView' used before being initialized
        )
    }
}

extension Menu: IChangeMenuItemHandler {
    func changeMenuItem() {
        print("1111")
        // self.currentMenuItem = .addonCreator
    }
}

我想实现一个方法,以便当单击 MenuMainView 类中的按钮时,会触发扩展 Menu 中的方法:IChangeMenuItemHandler。

extension Menu: IChangeMenuItemHandler {
    func changeMenuItem() {
        print("1111")
        // self.currentMenuItem = .addonCreator
    }
}
swift uikit
1个回答
0
投票

我可以回答您的两个问题。

  1. handlerChangeMenuItemDelegate: self
    :在类init中,可以使用self来引用类中的属性。然而作为一个对象的 self 还没有准备好。
    self
    正在处理以准备好作为对象,并在
    init
    范围末尾完成处理。这样这个代码就不会工作。例如。
    init{ self.someProperty = SomeType(x = 0 , q = self)}
    我可以参考self.someProperty,但我不能在
    q = self
    中将self用作完全初始化的对象。我希望你明白了。

  2. 我想实现一个方法,以便当单击 MenuMainView 类中的按钮时,会触发扩展 Menu 中的方法:IChangeMenuItemHandler

使

showMapsScene
作为您想要的按钮的选择器。然后
handlerChangeMenuItemDelegate?.changeMenuItem()
。在菜单中,使 mainMenuView.delegate = self.不要忘记遵守协议。就是这样。单击按钮时,它将触发 MenuMainView 中的选择器,这将触发委托,该委托将调用 Menu 类中的委托方法,您可以执行任何您想要的配置。

© www.soinside.com 2019 - 2024. All rights reserved.