Градиентный слой подпредставления CollectionViewCell существует только при первом поступлении View COntroller - PullRequest
2 голосов
/ 16 апреля 2019

У меня есть CollectionViewViewController, который отталкивается от другого.Это представление CollectionViewViewController имеет два подпредставления: простой UIView с меткой внутри и UICollectionView.Когда он представлен впервые, все работает совершенно нормально, а градиент отображается правильно.Но когда я вставляю этот View Controller (чтобы он был освобожден) и снова нажимаю его из того же родительского View Controlle, градиент не отображается.

Ячейка удаляется, как показано ниже:

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 подслоя в свою ячейку, но я уверен, что очищаю массив подслоев, так что я думаю, что это не проблема.

1 Ответ

0 голосов
/ 16 апреля 2019

layoutSubviews () не должен вызываться, приложение вызывает эту функцию самостоятельно при необходимости (вот почему она вызывается дважды в начале). Как указано на веб-сайте Swift Developer: https://developer.apple.com/documentation/uikit/uiview/1622482-layoutsubviews

Вы не должны вызывать этот метод напрямую.Если вы хотите принудительно обновить макет, вместо этого вызовите метод setNeedsLayout (), чтобы сделать это до следующего обновления чертежа.Если вы хотите немедленно обновить компоновку ваших представлений, вызовите метод layoutIfNeeded ().

Старайтесь избегать использования или вызова layoutSubviews (), вместо этого вы можете попытаться установить переменную градиента в функции и вызватьэто всякий раз, когда это нужно было вызвать, попробуйте ниже setupView ()

Дайте мне знать, если это помогло.

...