Применить градиент к метке в UICollectionViewCell - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь применить градиент к UILabel в одной из ячеек в моем UICollectionView.

После нескольких ответов в Интернете я добавил расширение к UIImage:

extension UIImage {
    static func gradientImageWithBounds(bounds: CGRect, colors: [CGColor]) -> UIImage {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = bounds
        gradientLayer.colors = colors
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

        UIGraphicsBeginImageContext(gradientLayer.bounds.size)
        if let context = UIGraphicsGetCurrentContext() {
            gradientLayer.render(in: context )
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return image!

        }
        return UIImage()
    }
}

, и когда я применяю его к обычному ярлыку, оно работает как шарм:

let gradientImage = UIImage.gradientImageWithBounds(bounds: someLabel.bounds, colors: [UIColor.black.cgColor, UIColor.white.cgColor])
someLabel.textColor = UIColor.init(patternImage: gradientImage)

Проблема в том, что метка, к которой я хочу применить градиент, является частью UICollectionViewCell, и когда я пытаюсь это сделать:

override init(frame: CGRect) {
        super.init(frame: frame)

        addSubview(nameLabel)
        nameLabel.snp.makeConstraints { (make) in
            make.top.bottom.trailing.equalToSuperview()
            make.leading.equalToSuperview().inset(10)
        }

        let gradientImage = UIImage.gradientImageWithBounds(bounds: nameLabel.bounds, colors: [UIColor.black.cgColor, UIColor.white.cgColor])
        nameLabel.textColor = UIColor.init(patternImage: gradientImage)
    }

, это не работает. Когда я остановил выполнение прямо перед созданием gradientImage, к сожалению, nameLabel.bounds равно 0:

(lldb) po nameLabel.bounds
▿ (0.0, 0.0, 0.0, 0.0)
  ▿ origin : (0.0, 0.0)
    - x : 0.0
    - y : 0.0
  ▿ size : (0.0, 0.0)
    - width : 0.0
    - height : 0.0

Есть ли способ получить границы для метки в определении UICollectionViewCell? Зависит ли это от того, как я определяю UICollectionView? Что мне не хватает?

В качестве альтернативы, знаете ли вы какой-либо другой способ иметь метку внутри UICollectionViewCell с градиентом?

Я попытался установить размер в:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 60)
}

Я попытался изменить определение макета с автоматического c на

layout.estimatedItemSize = CGSize(width: 100, height: 60)

Кажется, ничего не помогает.

1 Ответ

0 голосов
/ 17 июня 2020

Я думаю, проблема может быть в том, что вы асинхронно размещаете свои представления внутри замыкания. Другими словами, перед тем, как ваши представления будут выложены, выполняется следующий оператор, который объясняет, почему границы еще не установлены.

override init(frame: CGRect) {
        super.init(frame: frame)

        addSubview(nameLabel)
        nameLabel.snp.makeConstraints { (make) in
            make.top.bottom.trailing.equalToSuperview()
            make.leading.equalToSuperview().inset(10)
            let gradientImage = UIImage.gradientImageWithBounds(bounds: nameLabel.bounds, colors: [UIColor.black.cgColor, UIColor.white.cgColor])
            self.nameLabel.textColor = UIColor.init(patternImage: gradientImage)

        }
    }
...