5

I am trying to add Facebook Shimmer on UICollectionViewCell which has multiple UIViews.

For one UIView, it's working fine with below code:

let shimmeringView = FBShimmeringView(frame: imageView.frame)
shimmeringView.contentView = imageView
backgroundView.addSubview(shimmeringView)
shimmeringView.isShimmering = true

Where backgroundView is the view in which I have all the subviews such as imageView, labelView and others.

While I am trying to add multiple views then first view is getting correct frame but other views' widths are becoming zero. I'm adding this code inside collectionView(_:cellForItemAt:).

let shimmeringView = FBShimmeringView(frame: imageView.frame)
shimmeringView.contentView = imageView
backgroundView.addSubview(shimmeringView)
shimmeringView.isShimmering = true

let shimmeringView = FBShimmeringView(frame: labelView.frame)
shimmeringView.contentView = labelView
backgroundView.addSubview(shimmeringView)
shimmeringView.isShimmering = true

Can anyone tell me if it's the correct way to implement Facebook Shimmer for multiple UIViews or Where I am doing it wrong?

Arnab
  • 4,216
  • 2
  • 28
  • 50

2 Answers2

2

I believe there are many ways to implement FBShimmeringView, it's a matter of preferences. So in my case, I prefer the easiest way (according to me).

What I do in my tableViewCell that has of course multiple views such as imageView and labels, just like yours, is that I have multiple UIView gray color, placed on top of each views in my cell.

Then I only have ONE instance of FBShimmeringView added to my cell.

Here are some more details about what I practice for using FBShimmeringView.

*Take note that I use SnapKit to layout my views programmatically.

  1. I have a property in my cell called isLoading like so, which determines if the gray colored views should be shown or now. If shown, of course turn on shimmering:

    public var serviceIsLoading: Bool = false {
        didSet {
            _ = self.view_Placeholders.map { $0.isHidden = !self.serviceIsLoading }
            self.view_Shimmering.isHidden = !self.serviceIsLoading
            self.view_Shimmering.isShimmering = self.serviceIsLoading
        }
    } 
    
  2. Then I add a white view to my cell after adding all the subviews to the cell:

    // Place the FBShimmeringView
    // Try to add a dummy view
    let dummyView = UIView()
    dummyView.backgroundColor = .white
    self.addSubview(dummyView)
    dummyView.snp.makeConstraints { (make) in
        make.edges.equalToSuperview()
    }
    
  3. Add the ShimerringView to the cell as well:

    self.addSubview(self.view_Shimmering)
    self.view_Shimmering.snp.makeConstraints { (make) in
        make.height.width.equalToSuperview()
        make.center.equalToSuperview()
    }
    
  4. Finally, make the dummyView as the contentView of the cell:

    self.view_Shimmering.contentView = dummyView
    

My screen would look like this. Also remember to disable interaction in your tableView.

This looks cool to me when it shimmers, just one shimerring view.

enter image description here

Hope it helps!

Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95
1

Below extension is working fine.

extension UIView {
    func startShimmeringViewAnimation() {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
        let gradientColorOne = UIColor(white: 0.90, alpha: 1.0).cgColor
        let gradientColorTwo = UIColor(white: 0.95, alpha: 1.0).cgColor
        gradientLayer.colors = [gradientColorOne, gradientColorTwo, gradientColorOne]
        gradientLayer.locations = [0.0, 0.5, 1.0]
        self.layer.addSublayer(gradientLayer)

        let animation = CABasicAnimation(keyPath: "locations")
        animation.fromValue = [-1.0, -0.5, 0.0]
        animation.toValue = [1.0, 1.5, 2.0]
        animation.repeatCount = .infinity
        animation.duration = 1.25
        gradientLayer.add(animation, forKey: animation.keyPath)
    }
}

In UITableViewCell class, we need to add the Shimmer for each views.

class UAShimmerCell: UITableViewCell {
    @IBOutlet weak var thumbNailView: UIView!
    @IBOutlet weak var label1View: UIView!
    @IBOutlet weak var label2View: UIView!

    override func awakeFromNib() {
        super.awakeFromNib()
        thumbNailView.startShimmeringViewAnimation()
        label1View.startShimmeringViewAnimation()
        label2View.startShimmeringViewAnimation()
    }
}
Yano
  • 585
  • 3
  • 18