0

所以我有一个UIViewControllerUICollectionViewCompositionalLayout其中一个部分(最后一个)是一个列表。我UICollectionViewListCell为它配置了 2 个,但其中一个有问题(这个UICollectionView里面有一个)。不幸的是,我在控制台中遇到了配置错误:

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x7b14000adb10 V:|-(12)-[UIImageView:0x7b500017f800]   (active, names: '|':UIView:0x7b4800149700 )>",
    "<NSLayoutConstraint:0x7b14000adf20 UIImageView:0x7b500017f800.height == 20   (active)>",
    "<NSLayoutConstraint:0x7b14000adf70 V:[UIImageView:0x7b500017f800]-(>=20)-|   (active, names: '|':UIView:0x7b4800149700 )>",
    "<NSLayoutConstraint:0x7b14000a0960 'UIView-Encapsulated-Layout-Height' UIView:0x7b4800149700.height == 44   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7b14000adf70 V:[UIImageView:0x7b500017f800]-(>=20)-|   (active, names: '|':UIView:0x7b4800149700 )>

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x7b14000aea60 UICollectionView:0x7b7800092400.height == 50   (active)>",
    "<NSLayoutConstraint:0x7b14000a29e0 V:|-(12)-[UILabel:0x7b5400172000]   (active, names: '|':UIView:0x7b4800155b80 )>",
    "<NSLayoutConstraint:0x7b14000aea10 V:[UILabel:0x7b5400172000]-(15)-[UILabel:0x7b5400173680]   (active)>",
    "<NSLayoutConstraint:0x7b14000aeab0 V:[UILabel:0x7b5400173680]-(15)-[UICollectionView:0x7b7800092400]   (active)>",
    "<NSLayoutConstraint:0x7b14000aeba0 UICollectionView:0x7b7800092400.bottom <= UIView:0x7b4800155b80.bottom - 12   (active)>",
    "<NSLayoutConstraint:0x7b1400053de0 'UIView-Encapsulated-Layout-Height' UIView:0x7b4800155b80.height == 44   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7b14000aea60 UICollectionView:0x7b7800092400.height == 50   (active)>

如您所见,UIView-Encapsulated-Layout-Height返回默认值 44 而不是计算得出的值(应该在 144 左右)。

这是我的单元格配置,在配置列表单元格时有什么明显的或者我遗漏了什么吗?

class ActivityFeedAchievementListCell: UICollectionViewListCell {
    static let reuseIdentifier = "ActivityFeedAchievementListCell"
    private(set) var activity: UserActivity?
    let avatar: UIImageView = {
        let iconView = UIImageView(frame: .zero)
        iconView.contentMode = .scaleAspectFill
        iconView.layer.cornerRadius = 15.0
        iconView.layer.masksToBounds = true
        return iconView
    }()
    private let userNameLabel: UILabel = {
        let label = UILabel()
        label.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: UIFont(name: "Lato-Regular", size: 16.0)!)
        label.textColor = .white
        return label
    }()
    let platform: UIImageView = {
        let iconView = UIImageView(frame: .zero)
        iconView.contentMode = .scaleAspectFit
        return iconView
    }()
    private let timeLabel: UILabel = {
        let label = UILabel()
        label.font = UIFontMetrics(forTextStyle: .caption1).scaledFont(for: UIFont(name: "Lato-Light", size: 18.0)!)
        label.textColor = UIColor(white: 1.0, alpha: 0.5)
        return label
    }()
    private let descriptionLabel: UILabel = {
        let label = UILabel()
        label.font = UIFontMetrics(forTextStyle: .caption1).scaledFont(for: UIFont(name: "Lato-Light", size: 18.0)!)
        label.textColor = .white
        label.numberOfLines = 0
        return label
    }()
    private let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 0.0
        layout.minimumLineSpacing = 12.0
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.register(SingleAchievementCell.self, forCellWithReuseIdentifier: SingleAchievementCell.reuseIdentifier)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        return collectionView
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = .clear
        self.setupViews()
    }

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

    override func updateConfiguration(using state: UICellConfigurationState) {
        self.backgroundConfiguration = UIBackgroundConfiguration.clear()
    }

    private func setupViews() {
        let bgColorView = UIView()
        bgColorView.backgroundColor = UIColor(white: 1.0, alpha: 0.05)
        self.selectedBackgroundView = bgColorView
        self.backgroundColor = .clear
        self.contentView.addSubviews(views: self.avatar, self.userNameLabel, self.platform, self.timeLabel, self.descriptionLabel, self.collectionView)
        self.avatar.translatesAutoresizingMaskIntoConstraints = false
        self.userNameLabel.translatesAutoresizingMaskIntoConstraints = false
        self.platform.translatesAutoresizingMaskIntoConstraints = false
        self.timeLabel.translatesAutoresizingMaskIntoConstraints = false
        self.descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
        self.collectionView.translatesAutoresizingMaskIntoConstraints = false

        self.collectionView.delegate = self
        self.collectionView.dataSource = self

        NSLayoutConstraint.activate([
            self.avatar.widthAnchor.constraint(equalToConstant: 30.0),
            self.avatar.heightAnchor.constraint(equalToConstant: 30.0),
            self.avatar.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 12.0),
            self.avatar.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 20.0),
            self.userNameLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 12.0),
            self.userNameLabel.leftAnchor.constraint(equalTo: self.avatar.rightAnchor, constant: 15.0),
            self.platform.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 12.0),
            self.platform.leftAnchor.constraint(equalTo: self.userNameLabel.rightAnchor, constant: 15.0),
            self.timeLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 12.0),
            self.timeLabel.leftAnchor.constraint(equalTo: self.platform.rightAnchor, constant: 15.0),
            self.timeLabel.rightAnchor.constraint(lessThanOrEqualTo: self.contentView.rightAnchor, constant: -20.0),
            self.descriptionLabel.topAnchor.constraint(equalTo: self.userNameLabel.bottomAnchor, constant: 15.0),
            self.descriptionLabel.leftAnchor.constraint(equalTo: self.avatar.rightAnchor, constant: 15.0),
            self.descriptionLabel.rightAnchor.constraint(lessThanOrEqualTo: self.contentView.rightAnchor, constant: -20.0),
            self.collectionView.heightAnchor.constraint(equalToConstant: 50.0),
            self.collectionView.topAnchor.constraint(equalTo: self.descriptionLabel.bottomAnchor, constant: 15.0),
            self.collectionView.leftAnchor.constraint(equalTo: self.avatar.rightAnchor, constant: 15.0),
            self.collectionView.rightAnchor.constraint(lessThanOrEqualTo: self.contentView.rightAnchor, constant: -20.0),
            self.collectionView.bottomAnchor.constraint(lessThanOrEqualTo: self.contentView.bottomAnchor, constant: -12.0)
        ])
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        self.activity = nil
    }

    func configure(with item: ActivityGameItem) {
        if let activity = item.activity {
            self.activity = item.activity
            self.platform.image = UIImage(named: activity.gameReleaseKey.platform.userReadable())
            self.timeLabel.text = activity.eventTime
            self.descriptionLabel.attributedText = activity.description
        }

        if let user = item.user {
            if let avatar = user.imageUrl {
                self.avatar.af.setImage(withURL: avatar)
            }
            self.userNameLabel.text = user.username
        }

        self.collectionView.reloadData()
    }
}

// MARK: - UICollectionViewDataSource
extension ActivityFeedAchievementListCell: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        guard let activity = self.activity, let achievements = activity.achievements else { return 0 }
        return achievements.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SingleAchievementCell.reuseIdentifier, for: indexPath) as! SingleAchievementCell
        guard let activity = self.activity, let achievements = activity.achievements else { return cell }
        let item = achievements[indexPath.item]
        if let url = URL(string: item.imageURLUnlocked) {
            cell.achievementView.af.setImage(withURL: url)
        }
        return cell
    }
}

// MARK: - UICollectionViewDelegateFlowLayout
extension ActivityFeedAchievementListCell: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 50.0, height: 50.0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0, right: 0.0)
    }
}

// MARK: - UICollectionViewDelegate
extension ActivityFeedAchievementListCell: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let activity = self.activity, let achievements = activity.achievements else { return }
        let achievement = achievements[indexPath.item]
        log.info("Selected achievement with id: '\(achievement.achievementId)'.")
    }
}

4

0 回答 0