skip to Main Content

I created a UITableViewCell that is basically a card with a shadow behind it. I want to make this the base class used for all other custom UITableView Controllers. However, when I used the code below, the Shadowed Card doesn’t show up. Why is this?

ShadowCardTableViewCell

class ShadowCardTableViewCell: UITableViewCell {

    let borderView = UIView(frame: .zero)
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        changeToShadowedCard()
        self.contentView.layoutIfNeeded()
     }

     required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
    }
    
    func changeToShadowedCard() {
        backgroundColor = .clear
        contentView.addSubview(borderView)
        borderView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            borderView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
            borderView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -10),
            borderView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -10),
            borderView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 10),
        ])
        borderView.backgroundColor = .secondarySystemBackground
        borderView.layer.cornerRadius = 7.5
        borderView.addShadow(shadowColor: UIColor.label.cgColor, shadowOffset: CGSize(width: 0, height: 0), shadowOpacity: 0.3, shadowRadius: 4)
    }
}

OtherTableViewCell

class OtherTableViewCell: ShadowCardTableViewCell {

    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
     }

     required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
    }
}

2

Answers


  1. Firstly, you cannot make UITableViewCell a base class for a UiViewController.
    What you can do is provide an extension for you UITableViewCell, something along these lines:

    extension UITableViewCell {
        func setShadow() {
            layer.shadowColor = UIColor.lightGray.cgColor
            layer.shadowOpacity = 0.25
            layer.borderColor = UIColor.separator.cgColor
            layer.borderWidth = 1.0
            layer.cornerRadius = 10
            layer.shadowRadius = 1.0
            layer.shadowOffset = CGSize(width: 1.0, height: 1.0)
        }
    }
    

    and after registering a cell and initializing it, call it like:

    cell.setShadow()
    
    Login or Signup to reply.
  2. You haven’t shown what your borderView.addShadow(...) func is doing, but this is working fine for me:

    class ShadowCardTableViewCell: UITableViewCell {
        
        let borderView = UIView(frame: .zero)
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            changeToShadowedCard()
            // this line shouldn't be needed
            //self.contentView.layoutIfNeeded()
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            // this line needed if setting the cell class as a Prototype in Storyboard
            changeToShadowedCard()
        }
        
        func changeToShadowedCard() {
            backgroundColor = .clear
            contentView.addSubview(borderView)
            borderView.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                borderView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
                borderView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -10),
                borderView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -10),
                borderView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 10),
            ])
            borderView.backgroundColor = .secondarySystemBackground
            borderView.layer.cornerRadius = 7.5
            
            // not sure what you are doing here
            //borderView.addShadow(shadowColor: UIColor.label.cgColor, shadowOffset: CGSize(width: 0, height: 0), shadowOpacity: 0.3, shadowRadius: 4)
    
            // but this seems to work fine
            borderView.layer.shadowColor = UIColor.label.cgColor
            borderView.layer.shadowOffset = CGSize(width: 0, height: 0)
            borderView.layer.shadowOpacity = 0.3
            borderView.layer.shadowRadius = 4
        }
    }
    
    class OtherTableViewCell: ShadowCardTableViewCell {
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
        }
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    
    class SubCellVC: UITableViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // if you have not set your cell as a Storyboard Prototype
            //  register it here
            tableView.register(OtherTableViewCell.self, forCellReuseIdentifier: "otherCell")
            
            tableView.rowHeight = 60
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 20
        }
        
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "otherCell", for: indexPath)
            return cell
        }
    
    }
    

    Result:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search