OGeek|极客世界-中国程序员成长平台

标题: ios - CollectionViewCell 的 subview 的渐变层仅在 View COntroller 首次进入时存在 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-11 22:42
标题: ios - CollectionViewCell 的 subview 的渐变层仅在 View COntroller 首次进入时存在

我有一个 CollectionViewViewController 从另一个推送。这个 CollectionViewViewController 的 View 有两个 subview :简单的 UIView 和 UICollectionView。当它第一次出现时,一切正常,并且渐变显示正确。但是当我弹出这个 View Controller (所以它正在被释放)并从同一个父 View Controller 再次推送它时,没有显示渐变。

单元格出列如下:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PageScrollGeminiCellIdentifier, for: indexPath) as! PageScrollGeminiCell
    let item = viewModel.items[indexPath.item]
    cell.configure(withTitle: item.name, description: item. description, imageURL: item.imageUrl, gradientColor: item.color, theme: theme)
    mainView.geminiView.animateCell(cell)
    return cell
}

这是我在单元格的类方法和单元格生命周期中所做的:

private var gradientColor: UIColor?
private var gradientLayer: CAGradientLayer?
[...]
override init(frame: CGRect) {
    super.init(frame: .zero)
    setupView()
}
required init?(coder aDecoder: NSCoder) {
    return nil
}
override func layoutSubviews() {
    if gradientLayer != nil {
        gradientView.layer.sublayers = nil
    }
    if let color = gradientColor {
        let gradientPoints = (CGPoint(x: 0.0, y: 0.15), CGPoint(x: 0.0, y: 1.0))
        self.gradientLayer = gradientView.applyGradient(with: [color, color.withAlphaComponent(0.08)], gradient: .vertical(gradientPoints))
    }
}
// MARK: Private
private func setupView() {
    clipsToBounds = true
    layer.cornerRadius = 15
    backgroundColor = .clear
    addSubview(containerView)
    containerView.addSubview(backgroundImageView)
    containerView.addSubview(gradientView)
    containerView.addSubview(labelsContainerView)
    labelsContainerView.addSubview(titleLabel)
    labelsContainerView.addSubview(descriptionLabel)
    containerView.snp.makeConstraints { maker in
        maker.edges.equalToSuperview()
    }
    backgroundImageView.snp.makeConstraints { maker in
        maker.edges.equalToSuperview()
    }
    gradientView.snp.makeConstraints { maker in
        maker.leading.trailing.top.bottom.equalToSuperview()
    }
    labelsContainerView.snp.makeConstraints { maker in
        maker.leading.top.equalTo(16)
        maker.trailing.equalTo(-16)
    }
    titleLabel.snp.makeConstraints { maker in
        maker.top.leading.trailing.equalToSuperview()
    }
    descriptionLabel.snp.makeConstraints { maker in
        maker.top.equalTo(titleLabel.snp.bottom).offset(8)
        maker.leading.trailing.bottom.equalToSuperview()
    }
}
// MARK: - Internal
func configure(withTitle title: String?, description: String?, imageURL: String?, gradientColor: UIColor?, theme: Themeable) {
    backgroundImageView.setImage(withString: imageURL)
    titleLabel.text = title
    titleLabel.font = theme.font.h2
    descriptionLabel.text = description
    descriptionLabel.font = theme.font.b1
    self.gradientColor = gradientColor
}

我还想向你展示 applyGradient func:

func applyGradient(with colours: [UIColor], gradient orientation: GradientOrientation) -> CAGradientLayer {
    layoutSubviews()
    let gradient = CAGradientLayer()
    gradient.frame = self.bounds
    gradient.colors = colours.map { $0.cgColor }
    gradient.startPoint = orientation.startPoint
    gradient.endPoint = orientation.endPoint
    gradient.cornerRadius = layer.cornerRadius
    self.layer.insertSublayer(gradient, at: 0)
    return gradient
}

我发现,当第一次显示 View Controller 时,layoutSubviews() 方法被调用了两次,但下一次每个单元格只调用一次。

现在我不确定我是否没有向单元格插入超过 1 个子层,但我确定我正在清除子层数组,所以我认为这不是问题。



Best Answer-推荐答案


layoutSubviews() 不应该被调用,应用程序在需要时自己调用这个函数(这就是为什么它在开始时被调用两次) 如 Swift 开发者网站所述: https://developer.apple.com/documentation/uikit/uiview/1622482-layoutsubviews

You should not call this method directly. If you want to force a layout update, call the setNeedsLayout() method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded() method.

尽量避免使用或调用 layoutSubviews(),而是可以尝试在 func 中设置 gradientLayer 变量,并在需要调用时调用它,试试下面的 setupView()

如果有帮助,请告诉我。

关于ios - CollectionViewCell 的 subview 的渐变层仅在 View COntroller 首次进入时存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55707469/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4