• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - CollectionViewCell 的 subview 的渐变层仅在 View COntroller 首次进入时存在

[复制链接]
菜鸟教程小白 发表于 2022-12-11 22:42:26 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我有一个 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/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap