1
votes

Comment ajouter une contrainte à une sous-vue d'une instance de UIView sans que mon application ne plante?

J'ai une instance d'UIView dans Swift à laquelle j'ajoute une sous-vue d'une instance de UIImageView mais je ne peux pas ajouter de contrainte à l'instance UIImageView sans que mon application ne plante.

J'ai essayé d'écrire du code Swift 5.0 dans Xcode 10.2 et iOS 12.2 pour définir la contrainte selon laquelle le bord avant de l'instance UIImageView soit à 50 du bord gauche de l'instance UIView.

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
}

J'attends l'instance d'UIView contenant l'instance de UIImageView à positionner 50 à droite de l'instance de UIView. Au lieu de cela, l'application plante dans Xcode avec le message d'erreur "Thread 1: signal SIGABRT" dans le fichier AppDelegate.swift.


2 commentaires

Vous devez ajouter la vue à la hiérarchie en appelant addSubview avant de créer des contraintes entre parent et enfant.


J'ai ajouté sectionHeaderView.addSubview (sectionHeaderImageView) mais il plante toujours. Et j'obtiens le message d'erreur Une contrainte ne peut pas être faite entre un attribut de début / de fin et un attribut de droite / gauche. Utilisez le début / la fin pour les deux ou pour aucun des deux. "


3 Réponses :


0
votes

Cela fonctionne-t-il?

 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
}


1 commentaires

Non, il plante toujours avec le message d'erreur Impossible d'activer la contrainte avec les ancres et . La contrainte ou ses ancres référencent-elles des éléments dans différentes hiérarchies de vues? C'est illégal. »



0
votes

Ce code devrait fonctionner:

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
}


0 commentaires

0
votes

Vous devez d'abord ajouter une image à la vue parent

 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
}


2 commentaires

Merci @Yervand Saribekyan qui fonctionne! Pouvez-vous recommander une bonne ressource en ligne pour en savoir plus sur la définition de contraintes par programmation dans Swift? Merci.


Oui, bien sûr, voir des exemples dans la documentation Apple developer.apple .com / bibliothèque / archive / documentation /…