Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set drop shadow around a section for UITableView in iOS Swift 4?

I want to set shadow around a every section(group of cells) in iOS Swift. Like this:
enter image description here

like image 238
reza_khalafi Avatar asked Nov 05 '17 07:11

reza_khalafi


1 Answers

Easy to achieve this with UICollectionView ,

by subclass UICollectionViewFlowLayout with DecorationView

turn UITableViewCell into UICollectionViewCell ,

use decoration view to achieve the drop shadow of section part


class DecorationFlow: UICollectionViewFlowLayout {
    
    private var cache = [IndexPath: UICollectionViewLayoutAttributes]()
    
    override func prepare() {
        super.prepare()
        register(HistoDecorationV.self, forDecorationViewOfKind: HistoDecorationV.id)
        let originX: CGFloat = 15
        let widH: CGFloat = UI.std.width - originX * 2
        guard let collect = collectionView else{
            return
        }
        let sections = collect.numberOfSections
        var originY: CGFloat = 0
        for sect in 0..<sections{
            let sectionFirst = IndexPath(item: 0, section: sect)
            let attributes = UICollectionViewLayoutAttributes(forDecorationViewOfKind: HistoDecorationV.id, with: sectionFirst)
            let itemCount = collect.numberOfItems(inSection: sect)
            originY = originY + 80
            let h: CGFloat = 50 * CGFloat(itemCount)
            attributes.frame = CGRect(x: originX, y: originY, width: widH, height: h)
            originY = originY + h + 15
            cache[sectionFirst] = attributes
        }
    }
    
    
    
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
    
    
    private func prepareCache() {
      cache.removeAll(keepingCapacity: true)
      cache = [IndexPath: UICollectionViewLayoutAttributes]()
    }
    
    
    override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        
        return cache[indexPath]
        
    }

    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var array = super.layoutAttributesForElements(in: rect)
        guard let collection = collectionView, collection.numberOfSections > 0 else{
            return array
        }
        var z = 0
        array?.forEach({
            $0.zIndex = z + 100
            z += 1
        })
        z = 0
        for (_, attributes) in cache {
            
            if attributes.frame.intersects(rect){
                attributes.zIndex = z + 10
                array?.append(attributes)
            }
            z += 1
        }
        return array
    }
}

more code in github

like image 151
dengST30 Avatar answered Sep 27 '22 23:09

dengST30