Aditya Sharma
Aditya Sharma

Reputation: 605

Add shadow to every section in grouped table view

As shown in image I want to add shadow to my table view sections. As like table view has 4 section then there would be 4 shadow view in table view.

func numberOfSections(in tableView: UITableView) -> Int { return 3 }

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch processIndex {
        return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return  44
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 40
}

Upvotes: 9

Views: 8070

Answers (3)

Plato
Plato

Reputation: 651

This will set the shadow for only the sections and not the header/footer:

tableView.backgroundColor = .clear
tableView.subviews.forEach { view in
    view.layer.shadowColor = UIColor.darkGray.cgColor
    view.layer.shadowOpacity = 0.4
    view.layer.shadowOffset = .zero
    view.layer.shadowRadius = 3
}

Upvotes: 3

JPetric
JPetric

Reputation: 3918

There is an easier way to show shadow for every section.

  1. set the background color of your table view to UIColor.clear
  2. set table view style as Grouped (or for iOS 13+ you can even select Inset Grouped style which will also add corners to each section)
  3. add shadow to the whole table view. This will drop shadow to every section

To add shadow to the table view:

tableView.layer.masksToBounds = false
tableView.layer.shadowColor = UIColor.black.withAlphaComponent(0.4).cgColor // any value you want
tableView.layer.shadowOpacity = 1 // any value you want
tableView.layer.shadowRadius = 100 // any value you want
tableView.layer.shadowOffset = .init(width: 0, height: 10) // any value you want

Result

Upvotes: 15

McDonal_11
McDonal_11

Reputation: 4075

I have tried with custom [String : UIView] . This will work for minimum number of rows. If your cell's design is static, this will satisfy your design. If you want to access some property inside UITableViewCell, you have to go with subviews.

  • Multiple section with only one row. Only one view (lookView) inside that respective row.
  • We have to create n number of UIView programatically based on requirement.
  • UITapGesture to TableView . TableView format is Grouped, Separator as .none.

Following code will give output like:

screenShot

//Global Variable:


@IBOutlet weak var tblVw: UITableView!

var rowItemsDict = [String : [String]]()
var rowHeight = [String : CGFloat]()
var eachRowSubViews = [String : UIView]()


override func viewDidAppear(_ animated: Bool) {

    rowItemsDict = ["0" : ["welcome", "hello", "wow", "Good", "Bad"], "1" : ["Asia", "Europe", "America"], "2" : ["Mcdonald", "Pizza", "Fries"]]

    for i in 0..<rowItemsDict.count
    {
        let numOfSubItemsArr : [String] = rowItemsDict[String(i)]!
        let eachRowHeight : CGFloat = getShadowViewHeight(defaultHeight: 44.0, numberOfItems: numOfSubItemsArr.count)

        var subArrView = UIView()

        for j in 0..<numOfSubItemsArr.count
        {
            let sublabel = UILabel(frame: CGRect(x: 0, y: 0, width: tblVw.frame.size.width - 42, height: 39))
            sublabel.text = numOfSubItemsArr[j]
            sublabel.isUserInteractionEnabled = true
            sublabel.textAlignment = .right
            sublabel.textColor = UIColor.red
            let subView = UIView(frame: CGRect(x: 0, y: CGFloat((j * 40)), width: tblVw.frame.size.width, height: 39))
            subView.addSubview(sublabel)
            subView.backgroundColor = UIColor.clear
            subView.tag = ((i+1) * 100) + j

            if j == (numOfSubItemsArr.count - 1)
            {

            }
            else
            {
                let LinesubView = UIView(frame: CGRect(x: 0, y: 38, width: tblVw.frame.size.width - 8, height: 1))
                LinesubView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
                subView.addSubview(LinesubView)
            }

            subView.isUserInteractionEnabled = true
            subArrView.addSubview(subView)
            subArrView.isUserInteractionEnabled = true
        }

        eachRowSubViews[String(i)] = subArrView
        rowHeight[String(i)] = eachRowHeight
    }

    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapEachView))
    tblVw.addGestureRecognizer(tapGesture)
    tblVw.reloadData()
}


// TABLEVIEW DELEGATES
func numberOfSections(in tableView: UITableView) -> Int {


    return rowItemsDict.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SampleTableViewCell

    print("\n\ncellFor")
    cell.backgroundColor = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 0.0)
    cell.separatorVw.backgroundColor = UIColor(red: 250/255, green: 250/255, blue: 250/255, alpha: 0.0)
    tableView.clipsToBounds = true
    let gettingVw : UIView = eachRowSubViews[String(indexPath.section)]!
    cell.lookVw.addSubview(gettingVw)
    cell.lookVw.layer.cornerRadius = 10
    cell.separatorVw.backgroundColor = UIColor.clear

    cell.selectionStyle = .none
    return cell
}


func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    let cell = cell as! SampleTableViewCell

    cell.lookVw.dropOnlyOneShadowLeft(getSize: CGSize.zero)
    cell.lookVw.backgroundColor = UIColor.white


}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return (rowHeight[String(indexPath.section)]! )

}


//ROW HEIGHT CALCULATION
func getShadowViewHeight(defaultHeight: CGFloat, numberOfItems: Int) -> CGFloat
{
    let requiredHeight = CGFloat(Int(defaultHeight) * numberOfItems)

    return requiredHeight
}

//TAP GESTURE ACTION
@objc func tapEachView(sender: UITapGestureRecognizer)
{
    let touchPoint = sender.location(in: tblVw)
    let index = tblVw.indexPathForRow(at: touchPoint)

    if (index == nil)
    {
            print("long press on table view but not on a row");
    }
    else
    {
        let cell = tblVw.cellForRow(at: index!) as! SampleTableViewCell
        let pointInCell = cell.convert(touchPoint, from: tblVw)

        let innerSubVw = cell.lookVw.subviews
        print("pointInCellpointInCell)  ", pointInCell)
        for sVw in innerSubVw[0].subviews
        {
            let pointY = pointInCell.y - 5
            let comparePoint = sVw.frame.origin.y

            if pointY >= comparePoint && pointY <= comparePoint + 39
            {
                print("sVwsVwsVwsVwsVw    ", sVw.tag)

                //DO YOUR ACTION IN RESPECTIVE VIEW CLICK
                return
            }

        }

    }
}


extension UIView {
    func dropOnlyOneShadowLeft(getSize: CGSize) {
        self.layer.shadowColor = UIColor.lightGray.cgColor
        self.layer.shadowOpacity = 0.6
        self.layer.shadowOffset = getSize
        self.layer.shadowRadius = 3
    }
}

Upvotes: 3

Related Questions