Separating lines disappear when I choose adjacent cells - ios

I have a piece of code as follows (I have omitted the unnecessary parts):
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject) -> PFTableViewCell? {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as PFTableViewCell!
if cell == nil {
cell = PFTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
self.tableView.allowsMultipleSelection = true
self.tableView.separatorColor = UIColor.blueColor()
self.tableView.tableFooterView = UIView(frame:CGRectZero)
return cell
}
When I choose adjacent cells, the separating line between them disappears, which is not what I want. Is it possible to avoid this?

When you select any cell separator disappears. The solution is to add custom separators.

Try move the code below to viewDidLoad as it just need to be executed once:
self.tableView.allowsMultipleSelection = true
self.tableView.separatorColor = UIColor.blueColor()
self.tableView.tableFooterView = UIView(frame:CGRectZero)

Related

UITableView unexpected label changing

The cell is initially created from a xib file. Ive registered a reuse identifier in viewDidLoad().
Whenever I scroll down, one specific label is redrawn partially. Cant seem to figure out whats going on with the cell, but I know that the cell is not nil. Looking for insight on why this label isn't being drawn correctly.
before dragging
after dragging
More Info:
I can't tell, but it seems as if new cells are being drawn directly on top of the old cells. I figured this out due to the custom line divider: (let lineView = self.createLineDivider(cell: cell)) I added to context view of the cell. To stop the line from drawing over itself, I change the tag of every new cell.
override func viewDidLoad()
{
super.viewDidLoad()
let nib = UINib(nibName: "customContactDetailTableViewCell", bundle: nil)
self.contactDetailsTableView.register(nib, forCellReuseIdentifier: "customDetailCell")
}
func configureCell(cell: customContactDetailTableViewCell, indexPath: IndexPath) -> customContactDetailTableViewCell
{
let sectionName = self.props[indexPath.section].keys.first!
let contactPropLabel = self.props[indexPath.section][sectionName]![indexPath.row].keys.first!
let contactProp = self.props[indexPath.section][sectionName]![indexPath.row][contactPropLabel]
cell.contactDetailInfo?.layer.borderWidth = 1
cell.contactDetailInfo?.layer.borderColor = UIColor.white.cgColor
cell.contactDetailInfoTitle?.layer.borderWidth = 1
cell.contactDetailInfoTitle?.layer.borderColor = UIColor.white.cgColor
cell.contactDetailInfo?.numberOfLines = 0
cell.contactDetailInfoTitle?.text = contactPropLabel
cell.contactDetailInfo?.text = contactProp
cell.contactDetailInfo?.lineBreakMode = .byWordWrapping
self.rowHeight = cell.bounds.height
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{ var cell = tableView.dequeueReusableCell(withIdentifier: "customDetailCell") as? customContactDetailTableViewCell
if cell?.tag != 212
{
cell?.tag = 212
cell?.backgroundColor = UIColor.clear
let lineView = self.createLineDivider(cell: cell)
cell?.contentView.addSubview(lineView)
}
return self.configureCell(cell: cell!, indexPath: indexPath)
}
Update
Figured it out. Looks like the sporadic behavior came from the table view not updating the row height quick enough. Used this instead:
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}

xcode8 swift3 multiple UITableViews with custom cells with

Following up to the excellent write up of a ViewController with a single tableView, I'd like to extend the question to having 2 separate tableViews and custom cells belonging to each one independently.
At the moment, I have the following skeleton, which is semi-working, and I am sure there is a more elegant and less naive approach to solving this.
after the viewDidLoad()
vInfoTV.dataSource = self
vInfoTV.delegate = self
vInfoTV.tag = Int.min
vAppTV.dataSource = self
vAppTV.delegate = self
vAppTV.tag = Int.max
numberOfRowsInSection function
func tableView(_ tableView: UITableView, numberOfRowsInSection section:Int) -> Int {
if tableView.tag == Int.min {
return mydata.cats.count
} else {
return mydata.dogs.count
}
}
Is it appropriate to set the tableView's tags as I do here, and switch on them based on tag value?
Cells in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.tag == Int.min {
// Cat Table View
if indexPath.row == 0 {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "firstCustomCell")
//set the data here
return cell
}
else if indexPath.row == 1 {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "secondCustomCell")
//set the data here
return cell
}
else {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "thirdCustomCell")
//set the data here
return cell
}
} else {
// Dog Table View
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "poodleCell", for: indexPath) as! NewApplicationViewCell
cell.typeL.text = Dogs[(indexPath as NSIndexPath).row].type
return cell
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "mastifCell", for: indexPath) as! InitialDMVInspectionTableView
cell.typeL.text = Dogs[(indexPath as NSIndexPath).row].type
return cell
}
}
What is the best way to now hide a tableView, which has no cells (ie no data)?
Is this the right way to do this? All comments welcome!
THANK YOU!
Is it appropriate to set the tableView's tags as I do here, and switch on them based on tag value?
yes, you did exactly how I would do. Set the tag of your tables' differently. However I would not say Int.min or Int.max, rather I would want to know instantly what did I set as the tableviews' tag. So, I would just pick a number like 99 and 100. the reason I would not pick 0 and 1 is by default any object's tag is 0. So, if I put 99, I would be just keeping myself safe saying that even if someone comes and drag another table view inside my view, it will still not conflict with the ones before.
What is the best way to now hide a tableView, which has no cells (ie no data)?
Your tableview will not show up if you don't have data as in your numberOfRowsInSection, you set the row number to be the number of data in your desired data array.

Tap label in table view?

I have a label I want to tap on using addGestureRecognizer. I put it in cellForRowAtIndexPath but when I do print(label.text), it prints a label from another cell. But when I put it in didSelectRowAtIndexPath, it prints out the right label for that cell.
What is the best way to fix this?
Here is the code:
var variableToPass: String!
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell : MainCell! = tableView.dequeueReusableCellWithIdentifier("MainCell") as! MainCell
variableToPass = label1.text
cell.label1.userInteractionEnabled = true
let tapLabel = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapLabel(_:)))
cell.label1.addGestureRecognizer(tapLabel)
return cell as MainCell
}
func tapCommentPost(sender:UITapGestureRecognizer) {
print(variableToPass)
}
I think you forget to set the tap.tag = indexPath.row for identify which cell you tabbed for Find, for example
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell : MainCell! = tableView.dequeueReusableCellWithIdentifier("MainCell") as! MainCell
variableToPass = label1.text
cell.label1.userInteractionEnabled = true
let tapLabel = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapLabel(_:)))
cell.label1.tag = indexPath.row
tapLabel.numberOfTapsRequired = 1
cell.label1.addGestureRecognizer(tapLabel)
return cell as MainCell
}
func tapLabel(sender:UITapGestureRecognizer) {
let searchlbl:UILabel = (sender.view as! UILabel)
variableToPass = searchlbl.text!
print(variableToPass)
}
There are several issues with your current code: (1) You're setting variableToPass in cellForRowAtIndexPath:, so assuming label1.text is the label belonging to the cell, as the table loads, the variableToPass will always contain the label text of the last loaded cell. (2) cellForRowAtIndexPath: can be called multiple times for each cell (for example, as you scroll) so you could be adding multiple gesture recognizers to a single cell.
In order to resolve issue #1, remove the variableToPass variable entirely and instead directly access the gesture's label view. In order to resolve issue #2, I'd recommend adding the gesture recognizer to your custom MainCell table view cell, but if you don't want to do that, at least only add a gesture recognizer if one isn't already there.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MainCell") as! MainCell
if cell.label1.gestureRecognizers?.count == 0 {
cell.label1.userInteractionEnabled = true
let tapLabel = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapCommentPost(_:))) // I assume "tapLabel" was a typo in your original post
cell.label1.addGestureRecognizer(tapLabel)
}
return cell
}
func tapCommentPost(sender:UITapGestureRecognizer) {
print((sender.view as! UILabel).text) // <-- Most important change!
}

Is there a way of styling UITableViewCell in swift?

I have a table view and I am adding several cells to it based on my json.
So far the code for adding cells looks as follows:
override func viewWillAppear(animated: Bool) {
let frame:CGRect = CGRect(x: 0, y: 90, width: self.view.frame.width, height: self.view.frame.height-90)
self.tableView = UITableView(frame: frame)
self.tableView?.dataSource = self
self.tableView?.delegate = self
self.view.addSubview(self.tableView!)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CELL")
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}
let user:JSON = JSON(self.items[indexPath.row])
cell!.textLabel?.text = user["description"].string
var photoURL = "/path/to/my/icon/google.png"
if let data = NSData(contentsOfFile: photoURL)
{
cell!.imageView?.image = UIImage(data: data)
}
return cell!
}
Besides the description in my json I have also username and price. So far - since I'm adding only imageView and description, 3 cells look like this:
Is there a way to style it so that each cell looks similar to this:
(price and username are grey here`)? How can I achieve this effect?
===EDIT:
this is how I populate my table:
I'm fetching data from rest webservice to json:
func getAllUsers() {
RestApiManager.sharedInstance.getUsers { json in
let results = json
for (index: String, subJson: JSON) in results {
let user: AnyObject = JSON.object
self.items.addObject(user)
dispatch_async(dispatch_get_main_queue(),{
self.tableView?.reloadData()
})
}
}
}
and I invoke this method in my viewWillAppear function
You can make your table use custom UITableViewCells and style them to your liking.
In a nutshell, you create a prototype cell in Storyboard that looks like the example you posted and connect it to a custom UITableViewCell class with the elements you created. At cellForRowInIndexPath you return your custom cell rather than regular UITableViewCells.
Check out this tutorial for details: http://shrikar.com/uitableview-and-uitableviewcell-customization-in-swift/
Create the layout of the cell using a custom style. Place labels and imageView like you would anywhere else in storyborad.
You will need to create a UITableViewCell file. The one I used is named ExampleTableViewCell. Make note of the subclass.
Now connect your cell to the ExampleTableViewCell you just created.
Now we can make outlets from the labels and imageView of the cell into the ExampleTableViewCell. Control drag from each element into the ExampleTableViewCell.
The final step is to configure the cell using the cellForRowAtIndexPath func. Make note of the var cell. We now cast this to the ExampleTableViewCell. Once we do this we can use the outlets in the ExampleTableViewCell to set our labels and image. Make sure you set the resuseIdentifier for the cell in the storyboard. If you are unfamiliar with this leave a comment and I can add instructions for this.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier") as! ExampleTableViewCell
cell.imageDisplay.image = yourImage
cell.descriptionLabel.text = yourDescription
cell.priceLabel.text = yourPrice
cell.usernameLabel.text = yourUsername
return cell
}
Subclass UITableViewCell. You can go to the TableView on your storyboard and go to one of the prototypes and set it's class to your custom class and it's style to Custom and then you can ctrl+click & drag outlets/actions to the UITableViewCell subclass the same way you would for a basic view controller.

Converting Objective to Swift Table view not displaying the data in the cells

I'm still very inexperienced with Swift and am having a problem converting an objective-c based app.
Most of the app is working ... including changing size and colors of section headers and background color of the cells but I cannot display the content of the cells (a TextView and a switch).
Any suggestions about fixing this would be appreciated.
I'm including the code where I change the background color which is where I suspect the problem resides:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//variable type is inferred
var index = indexPath.row
NSLog ("index %d",indexPath)
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}
//we know that cell is not empty now so we use ! to force unwrapping
var grayishCyan = colorWithHexString("#9bc2c2")
var grayishRed = colorWithHexString("#ffc2c2")
if (indexPath.row == 0 || indexPath.row%2 == 0) {
cell!.backgroundColor = grayishCyan;
}
else {
cell!.backgroundColor = grayishRed
}
return cell!
} // end of cellForRowAtIndexPath
I removed the cellForRowAtIndexPath function and replaced it with the willDisplayCell function

Resources