我正在一个练习项目中,试图实现这一目标。
ios - Swift 4:UIView子类化,获取父 View-LMLPHP

使用UIView Subclassing差不多完成了,我和其他SF开发人员一起编写了此代码。

 class Luna: UIView {

     private var screenWidth: CGFloat {
        return UIScreen.main.bounds.width
     }

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

     }

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

     }

     public func showLuna(inView: UIView, title messageTitle:String, message messageDescription:String, dissmiss dissmissDuration: TimeInterval) {

        let luna = UIView()

        let titleLabel = UILabel()
        titleLabel.text = "Introducing our new football notifications on the Guardian app"
        titleLabel.font = UIFont(name: "avenirnext-demibold", size: 13)
        //titleLabel.textColor = UIColor(hexString: "4A4A4A")
        titleLabel.numberOfLines = 0 // whole idea of self-sizing

        let titleDesc = UILabel()
        titleDesc.text = "Today we are excited to announce the launch of our new and improved football notifications in our latest update to the Guardian app."
        titleDesc.font = UIFont(name: "avenirnext-regular", size: 9)
        //titleDesc.textColor = UIColor(hexString: "4A4A4A")
        titleDesc.numberOfLines = 0

        // My mainView

        luna.backgroundColor = .white
        //luna.addShadow(radius: 11, opacity: 0.2) // Some Shadow
        luna.layer.cornerRadius = 10

        let verticalStackView = UIStackView(arrangedSubviews: [titleLabel, titleDesc])
        verticalStackView.axis = .vertical

        let okButton = UIButton()
        okButton.setTitleColor(.blue, for: .normal)
        // okButton.setTitle("Okay", for: .normal)
        okButton.setContentHuggingPriority(.defaultHigh, for: .horizontal) // to stretch the okay button horizontally

        let horizontalStackView = UIStackView(arrangedSubviews: [verticalStackView, okButton])
        horizontalStackView.axis = .horizontal

        luna.addSubview(horizontalStackView)
        self.addSubview(luna)

        horizontalStackView.translatesAutoresizingMaskIntoConstraints = false // when using autolayout from code, this property must be false, otherwise constraint won't work
        luna.translatesAutoresizingMaskIntoConstraints = false


        NSLayoutConstraint.activate([
            horizontalStackView.topAnchor.constraint(equalTo: luna.topAnchor, constant: 8),
            horizontalStackView.bottomAnchor.constraint(equalTo: luna.bottomAnchor, constant: -8),
            horizontalStackView.leadingAnchor.constraint(equalTo: luna.leadingAnchor, constant: 8),
            horizontalStackView.trailingAnchor.constraint(equalTo: luna.trailingAnchor, constant: -8),

            luna.topAnchor.constraint(equalTo: inView.safeAreaLayoutGuide.topAnchor, constant: 30),
            luna.leadingAnchor.constraint(equalTo: inView.safeAreaLayoutGuide.leadingAnchor, constant: 30),
            luna.trailingAnchor.constraint(equalTo: inView.safeAreaLayoutGuide.trailingAnchor, constant: -30)
            ])

       }
}


但是,在另一个ViewController上调用Show Luna时,该应用程序崩溃并给出以下内容:


  2018-07-11 10:45:08.999314 + 0300 LunaView [1344:23604] ***终止
  应用程序由于未捕获的异常“ NSGenericException”,原因:“无法执行
  用锚激活约束,因为
  他们没有共同的祖先。约束或其锚点吗
  不同视图层次结构中的参考项目?那是非法的。


考虑到要提供的视图无效,我猜测该应用程序由于约束而崩溃。将Show Luna代码粘贴到另一个视图控制器的ViewDidLoad中是可行的,即如果将约束的InView更改为self.view,例如:

ios - Swift 4:UIView子类化,获取父 View-LMLPHP

但是我不能通过视图子类来做到这一点。甚至可以访问父级吗?

最佳答案

问题在于,您无需先在其中插入luna即可在luna和inView之间创建约束,因此在此行之后

 let luna = UIView()




 inView.addSubview(luna)

10-04 13:59