I want the header to mask the cells, but not the background.
I have a UITableView with transparent headers and cells similar to Apple\'s Notification Center (when yo
This wouldn't work if you wanted to show content behind your table view, but, since I'm only trying to create rounded headers with a plain solid colour background behind them, what solved it for me was mimicking transparency by setting the background colour of the header's background view to the background colour of the table view (or the first parent view with an opaque background).
Or, if all you need is for your UI to look nice, you could
In two quick and easy steps (iOS 6):
Change your UITableView style to UITableViewStyleGrouped. (You can do this from Storyboard/NIB, or via code.)
Next, set your tableview's background view to a empty view like so [in either a method such as viewDidAppear or even in the cellForRow method (though I would prefer the former)].
yourTableView.backgroundView = [[UIView alloc] initWithFrame:listTableView.bounds];
Voila, now you have your table view - but without the floating section headers. Your section headers now scroll along with the cells and your messy UI problems are solved!
Do try this out and let me know how it goes. Happy coding :)
EDIT: for iOS 7, simply change the table view style to 'UITableViewStyleGrouped' and change the view's tint color to 'clear color'.
The Swift 3 version didn't work for me because I added the UITableViewController as a subview. So I had to make some changes in the extension of the scrollview.
This should also work with UITableViewController that have been pushed from another ViewController (Note: not tested)
extension NavNotitionTableViewController {
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
for cell in tableView.visibleCells {
let calculatedY = cell.frame.origin.y - scrollView.contentOffset.y;
if let customCell = cell as? NavNotitionTableViewCell {
if(calculatedY < 44 && calculatedY > 0){
let hideAmount = 44 - calculatedY;
if let customCell = cell as? NavNotitionTableViewCell {
customCell.maskCell(fromTop: hideAmount)
}
}else if (calculatedY > 0){
//All other cells
customCell.maskCell(fromTop: 0)
}else if (calculatedY < 0){
customCell.maskCell(fromTop: cell.frame.height);
}
}
}
}
}
In this example, I first get the frame Y origin of the cell and distract the scollViews contentOffsetY.
The height of my custom section is 44. So I define the hideAmount value for the mask.
The Cell functions are untouched:
public func maskCell(fromTop margin: CGFloat) {
layer.mask = visibilityMask(withLocation: margin / frame.size.height)
layer.masksToBounds = true
}
private func visibilityMask(withLocation location: CGFloat) -> CAGradientLayer {
let mask = CAGradientLayer()
mask.frame = bounds
mask.colors = [UIColor.white.withAlphaComponent(0).cgColor, UIColor.white.cgColor]
let num = location as NSNumber
mask.locations = [num, num]
return mask
}
Clean Swift 3 Version:
extension YourViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
for cell in tableView.visibleCells {
let hiddenFrameHeight = scrollView.contentOffset.y + navigationController!.navigationBar.frame.size.height - cell.frame.origin.y
if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) {
if let customCell = cell as? CustomCell {
customCell.maskCell(fromTop: hiddenFrameHeight)
}
}
}
}
}
class CustomCell: UITableViewCell {
public func maskCell(fromTop margin: CGFloat) {
layer.mask = visibilityMask(withLocation: margin / frame.size.height)
layer.masksToBounds = true
}
private func visibilityMask(withLocation location: CGFloat) -> CAGradientLayer {
let mask = CAGradientLayer()
mask.frame = bounds
mask.colors = [UIColor.white.withAlphaComponent(0).cgColor, UIColor.white.cgColor]
let num = location as NSNumber
mask.locations = [num, num]
return mask
}
}
I just used this and it works like a charm. I want to thank everyone in the post! Up votes all around!