【问题标题】:Use of unimplemented initializer 'init(frame:)' for class when instantiating a subclass of UISegementedControl实例化 UISegementedControl 的子类时对类使用未实现的初始化程序“init(frame:)”
【发布时间】:2020-01-02 17:09:33
【问题描述】:

当我尝试在下面的代码中使用 MySegmentControl 的实例时出现以下错误。该错误在应用程序启动后立即发生。

知道我错过了什么吗?

致命错误:对“TestingSubclassing.MySegmentControl”类使用未实现的初始化程序“init(frame:)”

UISegementedControl 的子类

导入 UIKit

class MySegmentControl: UISegmentedControl {

    init(actionName: Selector) {
        let discountItems = ["One" , "Two"]
        super.init(items: discountItems)

        self.selectedSegmentIndex = 0

        self.layer.cornerRadius = 5.0
        self.backgroundColor = UIColor.red
        self.layer.borderWidth = 1
        self.layer.borderColor = UIColor.blue.cgColor

        self.addTarget(self, action: actionName, for: .valueChanged)
    }

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

视图控制器

import UIKit

class ViewController: UIViewController {

    let segmentOne: MySegmentControl = {
        let segment1 = MySegmentControl(actionName:  #selector(segmentAction))
        return segment1
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(segmentOne)
    }

    @objc func segmentAction (sender: UISegmentedControl) {
        print("segmentAction")
    }
}

【问题讨论】:

    标签: ios swift uisegmentedcontrol


    【解决方案1】:

    您可以调用super.init(frame手动插入片段

    而且你必须在自定义的init(actionName 方法中添加一个target 参数。

    class MySegmentControl: UISegmentedControl {
    
        init(actionName: Selector, target: Any?) {
            super.init(frame: .zero)
    
            insertSegment(withTitle: "Two", at: 0, animated: false)
            insertSegment(withTitle: "One", at: 0, animated: false)
            self.selectedSegmentIndex = 0
    
            self.layer.cornerRadius = 5.0
            self.backgroundColor = UIColor.red
            self.layer.borderWidth = 1
            self.layer.borderColor = UIColor.blue.cgColor
    
            self.addTarget(target, action: actionName, for: .valueChanged)
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    

    【讨论】:

    • 你真的打算在 0 索引处插入两个段还是应该在 1 处插入一个段?
    • 是的,我愿意。当One 被插入时Two 移动到索引1
    • @ vadian - 根据我的原始代码,我知道为什么会出错... 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[TestingSubclassing.MySegmentControl segmentActionWithSender:]: 无法识别的选择器发送到实例 0x7f8ec3507ef0'?我试过let segment1 = MySegmentControl(actionName: #selector(segmentAction(sender:)))let segment1 = MySegmentControl(actionName: "segmentAction"),但我一直收到同样的错误。
    • self 分配给子类中的目标是没有意义的。您必须添加一个target 参数。我更新了答案。
    猜你喜欢
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 2017-03-22
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多