Custom UITableView Header set background colour fail - ios

I created a custom UITableViewHeaderFooterView, and the tableview's background colour is white.
self.contentView.backgroundColor = UIColor.clearColor()
However, the section header's background always appears like gray. How can I remove the gray background??
Since I have override the drawRect func of the UITableView, so I want something to appear behind the header view.
I have tried the following:
a) Change the UITableView style to Grouped, the problem goes, but the header cannot glued on top of the table.
b) Use section header title instead of header view
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?
the header's background is transparent, but I have multiple labels.
Can anyone help me to figure this out?
Thanks to #Omkar, the correct way is set
cell.layer.backgroundColor = UIColor.clearColor().CGColor

You need to set the background colour of the content view to clear color and at the same time you also need to set the background color of the tableView cell to clear color. Place this in your viewForHeaderInSection method. You will then be able to see the color set to the tableView.
YourCell.contentView.backgroundColor = UIColor.clearColor()
YourCell.backgroundColor = UIColor.clearColor()
Please find the attached image for my code and also the table view whose style is plain style in storyboard. And i have also added the image of how it looks after running
Thanks

This is my ViewController code, the only difference is I use headerfootview subclass. I set the tableview's background to blue, and if i pull down a little bit, you will see there looks like a mask on header.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.registerClass(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "HeaderCell")
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 4
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath)
cell.textLabel?.text = "\(indexPath.row)"
return cell
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableHeaderFooterViewWithIdentifier("HeaderCell") as UITableViewHeaderFooterView!
cell!.textLabel?.text = "Header"
cell!.contentView.backgroundColor = UIColor.clearColor()
cell.backgroundColor = UIColor.clearColor()
return cell
}
}

Related

Swift UITableViewCell separatorStyle breaking autolayout on iPhone MIni

I have a UITableView which has a UITableViewCell which contains a UIImageView.
The constraints are setup such that the UIImageView has padding 20 points at the top and sides, and a size ratio of 1:1, so the UIImageView will always be square regardless of the device width.
I apply a cornerRadius to the UIImageView so the image is circular.
However.... the autolayout doesn't seem to work on the first load. But after the first load, it works perfectly.
I have tried every known combination of setNeedsLayout or layoutIfNeeded - both inside the UITableViewCell and in the UITableView code. Nothing works the first time it loads.
Please help!
Code looks like this:
class CircularProfileCell: UITableViewCell {
#IBOutlet weak var circularView: UIView!
func setup() {
circularView.layer.cornerRadius = circularView.bounds.height / 2
}
}
class CircularProfileVC: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.separatorStyle = .none
self.tableView.register(UINib(nibName: "CircularProfileCell", bundle: nil), forCellReuseIdentifier: "CircularProfileCell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CircularProfileCell", for: indexPath) as! CircularProfileCell
cell.setup()
return cell
}
}
Setup looks like this:
Because corner radius is a layer property it does not always play well with auto layout. In addition, I guess you set it up with frame properties of the view (i.e imageView.layer.cornerRadius = imageView.bounds.height/2).
Hence you should try and set the corner radius on the layoutSubviews() function of the cell. This will make sure to render the correct size
override func layoutSubviews() {
super.layoutSubviews()
imageView.layer.cornerRadius = imageView.bounds.height/2
...
}
This only happens when the tableView.separatorStyle = .none
So to fix it I simply leave the separator on, but set the separator color to clear
self.tableView.separatorStyle = .singleLine
self.tableView.separatorColor = UIColor.clear
Thanks to #CloudBalacing for the help. More info about this problem here

Two label align vertically in tableView cell auto resizing swift

Try to auto resizing two labels align vertically within a cell, is that possible?
In the storyboard, we have to set autolayout, since I want to auto resizing two labels(one is on top of another).
I can't set each height so that the storyboard doesn't know what is the height of these two labels so it shows an error for autolayout.
if I click "Add Missing Constraints" button it will add a height for "subtitle"
or I can set height for "title" rather than "subtitle",
or make "title" equal to "subtitle" it will still accept.
here is the result:
A workaround will be separate these two to a different cell.
Any better solution? or am I just simply forget to do anything?
P.S. I'm using Xcode 8 with iOS 10.3.
Try setting out Proper constraints for both the labels-:
Storyboard-:
Constraints for first label-:
Constraints for second label-:
Controller class(use Automatic Dimensions for table view)-:
class ViewController1: UIViewController {
var dataForTableView:[ProductImage]?
#IBOutlet weak var secondTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
secondTable.estimatedRowHeight = 96
secondTable.rowHeight = UITableViewAutomaticDimension
// CHECK FOR DATA
//print(dataForTableView?[0].url as Any)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController1 : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! testingCell2
cell.backgroundColor = UIColor.blue;
cell.secondLabel.text = "agfhjsgfhjsgdshgfhjsfjhvhssajs hjfbvhjfbvjhfgafgfhlgkaghkfakfhkflbvhfbvhfvbhfv ah fvfhbvfjhvbfhdavhfvhv"
return cell
}
// Number of sections in table
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}// Default is 1 if not implemented
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
return UITableViewAutomaticDimension
}
}
Output-:
I hope that is what you looking for, let me know if any issues.Thanks

How do I set the height for a custom UITableView?

I will be using a dynamic number of cells and resizing the height of the table on that basis. I could work out how to do this myself by I can't seem to resize the table. Whether I use 100 cells or 10 the view is set at the same height.
class generalTableViewController: UITableViewController {
override func viewWillAppear(_ animated: Bool) {
tableView.rowHeight = UITableViewAutomaticDimension
// self.tableView.contentSize.height = 2000
// self.tableView.frame.size.height = 2000
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1000
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
return cell
}
}
UITableViewControllers generally take over the entire view. To occupy only a portion of the view with a UITableView use a UIViewController.
You should use a UIViewController subclass rather than a subclass of UITableViewController to manage a table view if the view to be managed is composed of multiple subviews, only one of which is a table view. The default behavior of the UITableViewController class is to make the table view fill the screen between the navigation bar and the tab bar (if either are present).
See here for Apple guidance. You basically just need to take care of some of the things the controller would normally handle for you.

iOS Swift - How to change background color of Table View?

I have a simple table view, I can change the colors of cells, but when trying to change the color of Table View (Background part) it is not working... I tried it via Storyboard... Can someone please help
First set the background color of the tableView in viewDidLoad like below:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.backgroundColor = UIColor.lightGrayColor()
}
Now add this method:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.backgroundColor = UIColor.clearColor()
}
In Swift 3, use below methods instead of above one:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.backgroundColor = UIColor.lightGray
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor.clear
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.contentView.backgroundColor = UIColor.yellowColor()
}
Swift 3
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.contentView.backgroundColor = UIColor.yellow
}
If you want to achieve that via storyboard then select "Content View" of "table view cell" in your tableView then in attribute Inspector go to View and change its color like so:
use this code for change tableView color
override func viewDidLoad() {
super.viewDidLoad()
// define tableview background color
self.tableView.backgroundColor = UIColor.clearColor()
}
for change tableView cell color
cell.backgroundColor = UIColor.clearColor()
I'm a little late to the game! But, none of the above answers worked for me, so just going to share, what I found worked, in case anyone else is jumping on this thread.
NOTE: I also have my own custom cell class. Not sure if that will affect your code!
#IBDesignable class YourViewController: UITableViewController {
//IBInspectable and IBDesignable makes the properties accessible in storyboard
#IBInspectable var tableViewBackground: UIColor?
#IBInspectable var cellViewBackground: UIColor?
//in case you want to customize the text color, as well!
#IBInspectable var customTextColor: UIColor?
override func viewDidLoad() {
//your code
self.tableView.backgroundColor = tableViewBackground
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.textColor = customTextColor
cell.backgroundColor = cellViewBackground
return cell
}
//the rest of your code
}
Finding your inspectables:
1). In the Storyboard menu for the viewController of your tableView, click on yourViewController. The first dropdown inside the viewController. (The first dropdown will contain your tableView and cellView. It can also contain other goodies depending on your particular project).
2). In the attributes inspector, you'll see a heading with the name of your viewController and the #IBInspectable properties we defined above!!
3). You can then change them however you want there.
Hope this helps!
You have:
Cell background AND
Cell ContentView
Put ContentView like Default (transparent) in SB, and in your Cell's Method in awakeFromNib, just:
self.backgroundColor = UIColor.SomeColor

conditional Segue in Dynamic Prototype Cells

Another noob question but I could really do with some help on this one. I am looking for a way to have a list of cells in a dynamic prototype table view and each cell to go to a new view controller. I have managed to do this to about 75% :/. Basically I have made it work but it always loads the first cell first because its reuse identifier is called cell. Is there a way to make each one just load the View Controller I want? (code below)
Thanks
Sam
Edit 1: I have changed code to how it now looks below. But the Alton Barnes view controller is still loading in front of which ever cell you click and want to see.
import UIKit
class LocalAttractionsTableViewController: UITableViewController {
#IBOutlet weak var menuButton: UIBarButtonItem!
var Locations = ["Alton Barnes White Horse","Avebury","Barbury Castle","Bowood","Broad Town White Horse","Caen Locks","Cherhill White Horse","Corsham Court","Devices white Horse","Dragon Hill","Hackpen Hill White Horse","Iford Manor","Lacock","Longleat House","Longleat Safari Park","Marlborough white Horse","Pewsey White Horse","Salisbury Cathedral","Sheldon Manor","Silbury Hill","Stonehenge","The Barge Inn","Uffington White Horse","Westbury White Horse","West Kennet Long Barow","Wilton Windmill","Woodhenge"]
override func viewDidLoad() {
super.viewDidLoad()
// Side Menu
if self.revealViewController() != nil {
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
tableView.backgroundColor = UIColor.grayColor()
tableView.tableFooterView = UIView(frame:CGRectZero)
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 27
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Locations.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel!.text = Locations[indexPath.row]
cell.backgroundColor = UIColor.clearColor()
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{performSegueWithIdentifier(Locations[indexPath.row], sender:self);
}
}
I guess you have created the segues the wrong way.
If you have ctrl-dragged a segue from the prototype cell in InterfaceBuilder, this segue is performed without code. Then in your code you call performSegueWithIdentifier(...) which causes another segue to trigger.
You need to ctrl-drag all the segues from the tableViewController icon in InterfaceBuilder to the destination viewControllers and then give them the identifiers.
you created a segue with identifier name : Alton . Instead of "Alton" you need to rename the Segue identifier as Alton Barnes White Horse , later you need to do :
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {performSegueWithIdentifier(Locations[indexPath.row], sender:self);

Resources