【问题标题】:How do I add a constraint to a subview of an instance of UIView without my app crashing?如何在不崩溃的情况下向 UIView 实例的子视图添加约束?
【发布时间】:2019-04-04 10:41:28
【问题描述】:

我在 Swift 中有一个 UIView 实例,我在其中添加了一个 UIImageView 实例的子视图,但我无法在我的应用程序崩溃的情况下向 UIImageView 实例添加约束。

我曾尝试在 Xcode 10.2 和 iOS 12.2 中编写 Swift 5.0 代码来设置 UIImageView 实例的前沿距 UIView 实例的左边缘 50 的约束。

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let sectionHeaderView : UIView = UIView()

    let sectionHeaderImage: UIImage = UIImage(named: "Flag - ENGLAND.png")!
    let sectionHeaderImageView : UIImageView = UIImageView(image: sectionHeaderImage)
    sectionHeaderImageView.translatesAutoresizingMaskIntoConstraints = false

    let imageViewWidthConstraint : NSLayoutConstraint = NSLayoutConstraint(item: sectionHeaderImageView, attribute: .width, relatedBy: .equal, toItem: sectionHeaderImageView, attribute: .width, multiplier: 0.0, constant: 40)
    imageViewWidthConstraint.isActive = true
    sectionHeaderImageView.addConstraint(imageViewWidthConstraint)

    let imageViewHeightConstraint : NSLayoutConstraint = NSLayoutConstraint(item: sectionHeaderImageView, attribute: .height, relatedBy: .equal, toItem: sectionHeaderImageView, attribute: .height, multiplier: 0.0, constant: 40)
    imageViewHeightConstraint.isActive = true
    sectionHeaderImageView.addConstraint(imageViewHeightConstraint)

    let imageViewLeadingConstraint : NSLayoutConstraint = NSLayoutConstraint(item: sectionHeaderImageView, attribute: .leading, relatedBy: .equal, toItem: sectionHeaderView, attribute: .left, multiplier: 1.0, constant: 50)
    imageViewLeadingConstraint.isActive = true
    sectionHeaderImageView.addConstraint(imageViewLeadingConstraint)

    return sectionHeaderView
}

我希望包含 UIImageView 实例的 UIView 实例位于 UIView 实例右侧 50 处。相反,应用程序在 Xcode 中崩溃,并在文件 AppDelegate.swift 中显示错误消息“线程 1:信号 SIGABRT”。

【问题讨论】:

  • 在父子之间创建约束之前,您必须通过调用addSubview 将视图添加到层​​次结构中。
  • 我添加了sectionHeaderView.addSubview(sectionHeaderImageView),但它仍然崩溃。我收到错误消息A constraint cannot be made between a leading/trailing attribute and a right/left attribute. Use leading/trailing for both or neither.'

标签: swift uiview


【解决方案1】:

这行得通吗?

 override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let sectionHeaderView : UIView = UIView()

    let sectionHeaderImage: UIImage = UIImage(named: "Flag - ENGLAND.png")!
    let sectionHeaderImageView : UIImageView = UIImageView(image: sectionHeaderImage)
    sectionHeaderImageView.translatesAutoresizingMaskIntoConstraints = false

    let imageViewWidthConstraint : NSLayoutConstraint = NSLayoutConstraint(item: sectionHeaderImageView, attribute: .width, relatedBy: .equal, toItem: sectionHeaderImageView, attribute: .width, multiplier: 0.0, constant: 40)
    imageViewWidthConstraint.isActive = true
    sectionHeaderImageView.addConstraint(imageViewWidthConstraint)

    let imageViewHeightConstraint : NSLayoutConstraint = NSLayoutConstraint(item: sectionHeaderImageView, attribute: .height, relatedBy: .equal, toItem: sectionHeaderImageView, attribute: .height, multiplier: 0.0, constant: 40)
    imageViewHeightConstraint.isActive = true
    sectionHeaderImageView.addConstraint(imageViewHeightConstraint)

    let imageViewLeadingConstraint : NSLayoutConstraint = NSLayoutConstraint(item: sectionHeaderImageView, attribute: .leading, relatedBy: .equal, toItem: sectionHeaderView, attribute: .left, multiplier: 1.0, constant: 50)
    imageViewLeadingConstraint.isActive = true

    sectionHeaderView.addSubview(sectionHeaderImageView) // add subview first
    sectionHeaderImageView.addConstraint(imageViewLeadingConstraint)
    return sectionHeaderView
}

【讨论】:

  • 不,它仍然会崩溃并显示错误消息Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x2828fb100 "UIImageView:0x149e39d40.leading"> and <NSLayoutXAxisAnchor:0x2828fb180 "UIView:0x149e39890.trailing"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'
【解决方案2】:

这段代码应该可以工作:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let sectionHeaderView = UIView()
    let sectionHeaderImage = UIImage(named: "Flag - ENGLAND.png")!
    let sectionHeaderImageView = UIImageView(image: sectionHeaderImage)
    sectionHeaderImageView.translatesAutoresizingMaskIntoConstraints = false
    sectionHeaderView.addSubview(sectionHeaderImageView)

    NSLayoutConstraint.activate([
        sectionHeaderImageView.widthAnchor.constraint(equalToConstant: 40),
        sectionHeaderImageView.heightAnchor.constraint(equalToConstant: 40),
        sectionHeaderImageView.leadingAnchor.constraint(equalTo: sectionHeaderView.leadingAnchor, constant: 50),
        sectionHeaderImageView.topAnchor.constraint(equalTo: sectionHeaderView.topAnchor, constant: 50)
    ])
    return sectionHeaderView
}

【讨论】:

    【解决方案3】:

    首先你必须将图像添加到父视图

     override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let sectionHeaderView: UIView = UIView()
    
        let sectionHeaderImage: UIImage = UIImage(named: "Flag - ENGLAND.png")!
        let sectionHeaderImageView: UIImageView = UIImageView(image: sectionHeaderImage)
    
            sectionHeaderImageView.translatesAutoresizingMaskIntoConstraints = false
    
            sectionHeaderView.addSubview(sectionHeaderImageView)
    
            let imageViewHeightConstraint = NSLayoutConstraint(
                item: sectionHeaderImageView,
                attribute: .height,
                relatedBy: .equal,
                toItem: nil,
                attribute: .notAnAttribute,
                multiplier: 1.0,
                constant: 40
            )
            let imageViewWidthConstraint = NSLayoutConstraint(
                item: sectionHeaderImageView,
                attribute: .width,
                relatedBy: .equal,
                toItem: nil,
                attribute: .notAnAttribute,
                multiplier: 1.0,
                constant: 40
            )
            let imageViewLeadingConstraint = NSLayoutConstraint(
                item: sectionHeaderImageView,
                attribute: .left,
                relatedBy: .equal,
                toItem: sectionHeaderView,
                attribute: .left,
                multiplier: 1.0,
                constant: 50
            )
            sectionHeaderView.addConstraints([
                imageViewHeightConstraint,
                imageViewWidthConstraint,
                imageViewLeadingConstraint
                ])
        }
        return sectionHeaderView
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多