18

I have a tableview with three rows. I am trying to make the table rows have rounded corners and also a shadow effect around the entire tableview. For some reason, I cannot make the tableview both have the rounded corners and shadow effect but I could do them separately if I comment out the code responsible for one of the features. Here is the code I am using:

//this is for shadow effect

tableView.backgroundColor = UIColor.clearColor()

tableView.layer.shadowColor = UIColor.darkGrayColor().CGColor   

tableView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0

tableView.layer.shadowOpacity = 1.0

tableView.layer.shadowRadius = 2

// This is for rounded corners

tableView.layer.cornerRadius = 10

tableView.layer.masksToBounds = true
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
mitch94
  • 236
  • 1
  • 3
  • 11
  • Possible duplicate of [UIView with shadow, rounded corners and custom drawRect](http://stackoverflow.com/questions/25591389/uiview-with-shadow-rounded-corners-and-custom-drawrect) – Brian Nezhad Nov 19 '15 at 00:41
  • That doesn't work quite well since I am using a table view. – mitch94 Nov 19 '15 at 01:28
  • It should work, you're still editing the view layer. – Brian Nezhad Nov 19 '15 at 01:30
  • I am a bit confused as to how I could use my tableview instance. Could I make an IBOutlet for my table view and somehow use that in the answer from the link you provided? – mitch94 Nov 19 '15 at 01:35
  • Are you using `UITableViewController` or `UITableView` ? – Brian Nezhad Nov 19 '15 at 01:37
  • I am using a UITableView inside a view controller. – mitch94 Nov 19 '15 at 01:39
  • Then Yes, just drag and drop it and create an `IBOutlet` – Brian Nezhad Nov 19 '15 at 01:40
  • What would I replace in the link you provided with my uitableview? Would it be the superview variable or something else that I can't seem to figure out? – mitch94 Nov 19 '15 at 01:42
  • Yes, instead of `UIView`, you use `UITableView`, All you need to do is create an `IBOutlet` by drag and dropping it into your class file and in your `viewDidLoad:` method just do the same as the link i send you. – Brian Nezhad Nov 19 '15 at 01:45
  • I can't seem to get it still. Tried to change superview and shadow view to equal tableview but doesn't work. Here is what I currently have: https://pastee.org/8dh33 – mitch94 Nov 19 '15 at 01:58

4 Answers4

28

You can add your table view to a container view and add drop shadow to that container view:

let containerView:UIView = UIView(frame:CGRect(x: 10, y: 100, width: 300, height: 400))
self.tableView = UITableView(frame: containerView.bounds), style: .Plain)
containerView.backgroundColor = UIColor.clearColor()
containerView.layer.shadowColor = UIColor.darkGrayColor().CGColor   
containerView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
containerView.layer.shadowOpacity = 1.0
containerView.layer.shadowRadius = 2
// This is for rounded corners
self.tableView.layer.cornerRadius = 10
self.tableView.layer.masksToBounds = true
self.view.addSubview(containerView)
containerView.addSubview(self.tableView)

Edit

Swift 3.0:

let containerView:UIView = UIView(frame:CGRect(x: 10, y: 100, width: 300, height: 400))
self.tableView = UITableView(frame: containerView.bounds, style: .plain)
containerView.backgroundColor = UIColor.clear
containerView.layer.shadowColor = UIColor.darkGray.cgColor
containerView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
containerView.layer.shadowOpacity = 1.0
containerView.layer.shadowRadius = 2
    
self.tableView.layer.cornerRadius = 10
self.tableView.layer.masksToBounds = true
self.view.addSubview(containerView)
containerView.addSubview(self.tableView)

enter image description here

Community
  • 1
  • 1
beyowulf
  • 15,101
  • 2
  • 34
  • 40
  • containerView:UIView = UIView(frame:self.tableView.frame) is giving me an issue.. Don't seem to know what it is. If I change the first line to: "let containerView = UIView(frame:self.tableView.frame)", it force closes. – mitch94 Nov 19 '15 at 02:50
  • Be warned that this code will make the delete functionality stop working. – John Doe Nov 05 '16 at 08:19
  • @JohnDoe You're going to have to be more specific. I just ran this code and deleting worked fine. See the gif I attached to my answer. – beyowulf Nov 05 '16 at 17:41
  • That is odd. Yesterday I could swipe but not tap the delete button. But now the swipe would not work at all on my actual project. Just now I created a fresh project, swipe does work but tapping delete does nothing. I tried putting the code in `viewDidAppear`, `viewWillAppear`, `viewWillLayoutSubviews`. Removing the code makes it work, or by changing the last line to `self.view.addSubview(tableView)` similar to the next answer – John Doe Nov 06 '16 at 02:54
  • 1
    @JohnDoe [This](https://gist.github.com/bgayman/18471d780a8a47916e8e312d47c5ad7f) is the code I used to test that. ¯\_(ツ)_/¯ – beyowulf Nov 06 '16 at 13:20
  • I commented out the references to `PlaygroundSupport` and it does indeed work – John Doe Nov 06 '16 at 13:42
  • I know now why the code above does not work for me. You need to change the hard-coded first line to `let containerView:UIView = UIView(frame: tableView.frame)` – John Doe Nov 06 '16 at 13:52
  • I had it that way before when you first mentioned it didn't work, but that won't make sense for all case, so I changed it to something arbitrary. I thought it was implied to use something sensible. Like the container view can have some origin, but if you are adding the table view as a subview of the container view, then the table view's origin should be `CGPoint.zero` and the table view and container view's size should be equal. I'll make that more clear in my answer. Sorry for the confusion. – beyowulf Nov 06 '16 at 23:24
  • Nice solution, neat way to get a border on a table. – matthew Mar 29 '19 at 19:24
5

The RDC's answer is good, but for me the result didnt resolve my case, follow is my fix :

//for table view border
tableView.layer.borderColor = UIColor .grayColor().CGColor
tableView.layer.borderWidth = 1.0

//for shadow
let containerView:UIView = UIView(frame:self.tableView.frame)
//dont use clear color,fit blue color
containerView.backgroundColor = UIColor.blueColor()
//shadow view also need cornerRadius
containerView.layer.cornerRadius = 10
containerView.layer.shadowColor = UIColor.lightGrayColor().CGColor
containerView.layer.shadowOffset = CGSizeMake(-10, 10); //Left-Bottom shadow
//containerView.layer.shadowOffset = CGSizeMake(10, 10); //Right-Bottom shadow
containerView.layer.shadowOpacity = 1.0
containerView.layer.shadowRadius = 2

//for rounded corners
tableView.layer.cornerRadius = 10
tableView.layer.masksToBounds = true
self.view.addSubview(containerView)
self.view.addSubview(tableView)
Chris Ho
  • 295
  • 4
  • 13
3

i tried above solution but in my application tableview didSelectRowAt was not working.

use this Extension for UITabeleView for corner for shadow

//if u want shadow for all side use (shadowOffset = .zero)

extension UITableView {
    func addCorner(){
        self.layer.cornerRadius = 15
        self.clipsToBounds = true
    }

    func addShadow(){
        self.layer.shadowColor = UIColor.lightGray.cgColor
        self.layer.shadowRadius = 5
        self.layer.shadowOpacity = 0.5
        self.layer.shadowOffset = .zero
        self.layer.masksToBounds = false
    }
}

How to use::

   self.tableView.addCorner()
   self.tableView.addShadow()
iOS_Tejas
  • 209
  • 2
  • 9
2

Thanks to @beyowulf

I have upgraded for me with Swift 2.2, to

  • set Border,
  • Rounded corner and
  • Drop shadow to the table view

    //for table view border
    tableView.layer.borderColor = UIColor .grayColor().CGColor
    tableView.layer.borderWidth = 1.0
    
    //for shadow
    let containerView:UIView = UIView(frame:self.tableView.frame)
    containerView.backgroundColor = UIColor.clearColor()
    containerView.layer.shadowColor = UIColor.lightGrayColor().CGColor
    containerView.layer.shadowOffset = CGSizeMake(-10, 10); //Left-Bottom shadow
    //containerView.layer.shadowOffset = CGSizeMake(10, 10); //Right-Bottom shadow
    containerView.layer.shadowOpacity = 1.0
    containerView.layer.shadowRadius = 2
    
    //for rounded corners
    tableView.layer.cornerRadius = 10
    tableView.layer.masksToBounds = true
    self.view.addSubview(containerView)
    containerView.addSubview(tableView)
    

result looks like

enter image description here

swiftBoy
  • 35,607
  • 26
  • 136
  • 135
  • the code works but y position strange, let's try modify clearColor() line to containerView.backgroundColor = UIColor.blueColor(); add containerView.layer.cornerRadius = 10; modify containerView.addSubview(tableView) to [code]self.view.addSubview(tableView);[/code] – Chris Ho Apr 22 '16 at 08:31