从超类 UIView 连接的 IBoutlet 仍然为零

IBoutlet Connected From SuperClass UIView Still Nil

我使用 Nibs。我有两个屏幕将使用具有相同行为的 "same" UIView 组件。它不是同一个组件,因为在每个屏幕中我都放置了一个 UIView 并进行了相同的配置,如图所示。

为了解决这个问题并防止在其他 classes 中复制相同的代码,我写了一个 class,这是一个 UIView subclass,具有所有功能我需要。

之后我将我的自定义 class 作为这些 UIView 组件的超级 class 来继承 IBOutlets 和所有功能。

我的自定义class没有在Nib中定义,只是.swiftclass.

我进行了所有必要的连接,但在 运行 时 IBOutletsNil

我的自定义代码class:

class FeelingGuideView: UIView {

    @IBOutlet weak var firstScreen: UILabel!
    @IBOutlet weak var secondScreen: UILabel!
    @IBOutlet weak var thirdScreen: UILabel!
    @IBOutlet weak var fourthScreen: UILabel!

    private var labelsToManage: [UILabel] = []
    private var willShow: Int!
    private var didShow: Int!

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.initLabelManagement()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.initLabelManagement()
    }

    private func initLabelManagement() {
        self.initLabelVector()
        self.willShow = 0
        self.didShow = 0
        self.setupLabelToShow(label: labelsToManage[0])
        self.setupLabels()
    }

    private func initLabelVector() {
        self.labelsToManage.append(self.firstScreen)
        self.labelsToManage.append(self.secondScreen)
        self.labelsToManage.append(self.thirdScreen)
        self.labelsToManage.append(self.fourthScreen)
    }

    private func setupLabels() {

        for label in labelsToManage {
            label.layer.borderWidth = 2.0
            label.layer.borderColor = UIColor(hex: "1A8BFB").cgColor
        }
    }

    func willShowFeelCell(at index: Int) {
        self.willShow = index

        if willShow > didShow {
            self.setupLabelToShow(label: labelsToManage[willShow])
        }
        else if willShow < didShow {

            for i in didShow ... willShow + 1 {

                let label = labelsToManage[i]
                self.setupLabelToHide(label: label)
            }
        }
    }

    private func setupLabelToShow(label: UILabel) {
        label.textColor = UIColor.white
        label.backgroundColor = UIColor(hex: "1A8BFB")
    }

    private func setupLabelToHide(label: UILabel) {
        label.textColor = UIColor(hex: "1A8BFB")
        label.backgroundColor = UIColor.white
    }
}

我发现这个问题与我的相似:Custom UIView from nib inside another UIViewController's nib - IBOutlets are nil

但是我的UIView不在笔尖里。

编辑:

我重写了 awakeFromNib 但它没有进入方法。

更多说明:

我的自定义 class 只是这个组件的超类:

我在两个屏幕上复制。

一个屏幕是 UITableViewCell,另一个屏幕是 UIViewController

这一切都是为了根据 UICollectionView

上当前显示的屏幕来管理标签的行为

当在 required init?(coder aDecoder:) 处调用 initLabelVector() 函数时,会出现解包错误:

打开View报错:

无法显示 UITableViewCell 的错误,因为它是在应用程序开始时调用的,不会出现任何内容。为了在屏幕上显示错误,我需要删除 UITableViewCell 的调用。

UITableViewCell先注册到tableView.register(nib:),再使用tableView.dequeueReusebleCell

UIViewController 是从菜单 class 中调用的:

startNavigation = UINavigationController(rootViewController: FellingScreenViewController())
appDelegate.centerContainer?.setCenterView(startNavigation, withCloseAnimation: true, completion: nil)

当我的自定义 class 中的 init() 被调用时,IBOutlets 尚未连接。

因此,我在父视图上创建了一个引用并从 viewDidLoad() 方法调用了 iniLabelManagement(),一切正常。

谢谢马特的帮助和耐心等待!

问题是这段代码:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.initLabelManagement()
}

问题在于 init(coder:)太早 无法谈论视图的出口,而 initLabelManagement 正是这样做的;插座尚未连接。改为:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}
override func awakeFromNib() {
    super.awakeFromNib()
    self.initLabelManagement()
}

我是如何得到这个答案的:

作为测试,我尝试了这个:

class MyView : UIView {
    @IBOutlet var mySubview : UIView!
    required init?(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
        print(#function, self.mySubview)
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        print(#function, self.mySubview)
    }
}

这是输出:

init(coder:) nil
awakeFromNib() <UIView: 0x7fc17ef05b70 ... >

这证明了什么:

  • init(coder:) 太早了;插座还没有接通

  • awakeFromNib太早了;插座 连接

  • awakeFromNib 被称为,尽管你的说法与此相反