【问题标题】:Dynamic Creation UIButton AddTarget on UIView executed on UIViewController在 UIViewController 上执行的 UIView 上的动态创建 UIButton AddTarget
【发布时间】:2020-01-11 12:35:29
【问题描述】:

当前执行标记样式列表的代码,当我想尝试将 addTarget 操作 optionClicked 传递给我的 UIViewController

时,问题仍然存在

DrawerView.swift


let menuOptions = ["Info", "Actions", "Users", "Patiens"]

        menuOptions.forEach({

            let button = UIButton()
            button.setTitle($0, for: .normal)

            if $0.contains(menuOptions[0]) {
                button.style(with: .filled)
            } else {
                button.style(with: .outlined)
                button.addTarget(self, action: #selector(optionClicked(_:)), for: .touchUpInside)
            }
            actionStackView.addArrangedSubview(button)
        })

DrawerController.swift


class DrawerController: UIViewController {

    var shareView = DrawerView()
    var viewModel: CarDetailViewModel?

    override func loadView() {
        shareView.viewModel = viewModel
        view = shareView
    }

    @objc func optionClicked(_ sender: UIButton) {

        let feedbackGenerator = UISelectionFeedbackGenerator()
        feedbackGenerator.selectionChanged()

        let optionClicked: String = sender.titleLabel?.text ?? "0"

        switch optionClicked {
        case "Actions": present(DrawerActionController(), animated: true, completion: nil)
        case "Notifications":
            let viewController = DrawerNotificationController()
            viewController.carDetailViewModel = viewModel
           present(viewController, animated: true, completion: nil)

        case "Patients":
            let viewUserController = DrawerUserController()
            viewUserController.carPath = "9000"
           present(viewUserController, animated: true, completion: nil)
        default: break
        }
    }
}

试过 button.addTarget(self, action: #selector(optionClicked(_:)), for: .touchUpInside) 但没有成功。

【问题讨论】:

  • 检查界面生成器。可能是您将按钮与视图控制器连接,然后从视图控制器中删除了代码,但错过了连接。
  • @AlexanderVolkov 我没有使用情节提要。都是代码。
  • 看起来目标是视图?您需要将操作的目标设置为视图控制器,或者设置路径以便视图可以将操作传达给视图控制器(例如,通过委托)。
  • @3ddpaz 然后检查您的代码在哪里。看起来self 的目标是视图控制器。将其更改为您的视图,您有 optionClicked 方法。
  • @AlexanderVolkov 将 uiviewcontroller 中的 self 作为委托添加到 uiview 并将其添加到 addTarget 上的 self 没有发生任何事情。

标签: ios swift uiview uiviewcontroller uiview-hierarchy


【解决方案1】:

button.addTarget(self, action: #selector(optionClicked(_:)), for: .touchUpInside) 方法中,您需要提供指向将接收操作的 viewController 的指针。

在您的情况下,最简单的方法是在初始化时使用 DrawerController 创建惰性变量 DrawerView,并在按钮操作中使用抽屉控制器。

DrawerView.swift

class DrawerView: UIView {

    private unowned let drawerController: DrawerController

    init(drawerController: DrawerController) {
        self.drawerController = drawerController
    }

    ... wherever is your code placed ...

    let menuOptions = ["Info", "Actions", "Users", "Patiens"]

    menuOptions.forEach({

        let button = UIButton()
        button.setTitle($0, for: .normal)

        if $0.contains(menuOptions[0]) {
            button.style(with: .filled)
        } else {
            button.style(with: .outlined)
            button.addTarget(drawerController, action: #selector(DrawerController.optionClicked(_:)), for: .touchUpInside)
            actionStackView.addArrangedSubview(button)
        }
    })

    ....
}

请务必使用 unownedweak 来防止保留循环和内存泄漏

要创建 DrawerView,您可以使用惰性变量:

lazy var shareView: DrawerView = DrawerView(drawerController: self)

lazy 将允许你使用 self,你也可以使用 optional 并稍后创建变量,但这基本上就是 lazy 所做的。

希望对您有所帮助!

【讨论】:

  • 尝试实施您的解决方案但我明白了。 “DrawerController”类型的值没有成员“optionClicked”
  • @3ddpaz 我刚刚实现了它,它对我来说工作正常。如果没有帮助,您可以尝试清理项目Product > Clean build folder 并重新启动 Xcode 吗?我没有看到代码本身有任何问题,您是否使用了任何访问修饰符,例如 privatefileprivate
猜你喜欢
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 2011-07-03
  • 1970-01-01
相关资源
最近更新 更多