Swift - UITableViewCell label position is shifted after scrolling - swift

The Table View Cells are laid out correctly during the initial load, but when I scroll up or down, the labels are shifted to the left. I'm not sure what is going on here.
My code for the tableview cell is below.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let workout = self.workouts[indexPath.row] as? Workout
let cell = tableView.dequeueReusableCellWithIdentifier("WorkoutCell") as? WorkOutCell
cell!.textCell?.text = workout?.title
cell!.backgroundColor = workout?.color
cell!.countLabel.text = "\(indexPath.row+1)"
cell!.selectionStyle = UITableViewCellSelectionStyle.None
return cell!
}
Image:
Thanks much!

Is there any changes if use this instead?
let cell = tableView.dequeueReusableCellWithIdentifier("WorkoutCell", forIndexPath: indexPath) as? WorkOutCell

Related

Multiple UITableViewCells each with UIProgressView very slow to update

I am making a game which has 10 UITableViewCells in a UITableView. Each of the 10 UITableViewCells has one UIProgressView plus a lot of other views. I update the UITableView every 1/10th of a second, this is very slow and lags on older devices. I update it every 1/10th second for UX, gives a smooth progress view feel to game.
Is there a way to just update just the Progress Views in each cell individually rather than having to call the tableView.reloadData() that will update all the views in each cell?
Code example:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "businessCell", for: indexPath) as! BusinessCell
cell.progress.progress = Float( businessArray[indexPath.row-1].getCurrentProgress() )
//lots of other views are updated here
return cell
}
}
could I maybe change this line:
cell.progress.progress = Float( businessArray[indexPath.row-1].getCurrentProgress() )
to something like this:
cell.progress.progress = someVarLocalToViewControllerContainingTableView[indexPath.row]
and when I update this local var it would update only the progressView or something?
I have tried many ways but cannot figure out how to do this...
If you need to update a progress for a specific cell, then call this
func reloadProgress(at index: Int) {
let indexPath = IndexPath(row: index, section: 0)
if let cell = tableView.cellForRow(at: indexPath) as? BusinessCell {
cell.progress.progress = Float( businessArray[index - 1].getCurrentProgress() )
}
}
If you need to reload all bars in the table:
func reloadProgress() {
for indexPath in tableView.indexPathsForVisibleRows ?? [] {
if let cell = tableView.cellForRow(at: indexPath) as? BusinessCell {
cell.progress.progress = Float( businessArray[indexPath.row - 1].getCurrentProgress() )
}
}
}
you can use :
self.tableView .reloadRows(at: <[IndexPath]>, with: <UITableViewRowAnimation>)
rather than using tableView.reloadData()
Please check below link:
Is it possible to refresh a single UITableViewCell in a UITableView?
It might help in your scenario.

A sub view in UITableview gets disappear once the row is been clicked.

I'm working on a project in swift 3.0 where I have a UIView inside a UITableViewCell. For some reason once a row is been selected the view gets disappear, and once a a new row is been selected the view of the previous cell shows up and the view of the newly selected one gets disappear.Name of the view that gets disappear is redView(reference of the code bellow). My code and UITableView delegates as follow.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.clear
cell.selectedBackgroundView = backgroundView
let data = self.mediaList[indexPath.row] as! NSDictionary
let redView = cell.viewWithTag(TABLE_CELL_TAGS.redView)!
let reducedPriceLabel = cell.viewWithTag(TABLE_CELL_TAGS.reducedpricelable) as! UILabel
Utils.setTableCellLabelText(cell: cell, labelTag: TABLE_CELL_TAGS.title, text: data["title"] ?? "title...")
if let reducedPrice = data["mediaValue"] as? Int{
reducedPriceText = "$\(String(reducedPrice))"
redView.isHidden = false
reducedPriceLabel.isHidden = false
}else{
redView.isHidden = true
reducedPriceLabel.isHidden = true
}
Utils.setTableCellLabelText(cell: cell, labelTag: TABLE_CELL_TAGS.reducedpricelable, text: reducedPriceText)
return cell;
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let mP3ViewController = self.storyboard?.instantiateViewController(withIdentifier:"MP3ViewController") as! MP3ViewController
mP3ViewController.mediaDetails = mediaList[indexPath.row] as? NSDictionary
self.navigationController?.pushViewController(mP3ViewController, animated:true)
}
Go to the storyboard setting of tableViewcell set selection to None. then I think it will work for you.
Try this and let me know.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let mP3ViewController = self.storyboard?.instantiateViewController(withIdentifier:"MP3ViewController") as! MP3ViewController
mP3ViewController.mediaDetails = mediaList[indexPath.row] as? NSDictionary
self.navigationController?.pushViewController(mP3ViewController, animated:true)
}

Dynamic TableViewCell | Swift

I have 2 custom cells: 1 for image, 2 for text (using label to display).
I want text-cell to be dynamic height, depending on text size.
Set lines of label to 0, used top, left and right constraints, but when i add info to array, reload it - then table displays nothing.
Also in viewDidLoad coded next:
articleTableView.estimatedRowHeight = 150
articleTableView.rowHeight = UITableViewAutomaticDimension
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
if content[indexPath.row].rangeOfString("imageBase64") == nil {
let cell = self.articleTableView.dequeueReusableCellWithIdentifier("Text Cell", forIndexPath: indexPath) as! TextTableViewCell
cell.textArticle.text = content[indexPath.row] as String
}
else{
let cell = self.articleTableView.dequeueReusableCellWithIdentifier("Image Cell", forIndexPath: indexPath) as! ImageTableViewCell
cell.imageArticle.image = decodedImage
}
return UITableViewCell()
}
What's the problem here?
You need to return cell not return UITableViewCell()

Swift - change height of mapview inside a tableView

(Look at ##Edit##)
I'm a beginner. I used google but can't find a solution for my problem.
How can I change the height of my MapView inside the tableView?
My storyboard looks like:
click here I cant post pictures
I can change the size of the MKMapView however I want but nothing changed "in real/in the emulator".
I tried to change the size of the cells with:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(indexPath.row == 0) {
return 500
}
return 75.0
}
But indexPath.row=0 ist the first entry "Name: Test"
Can somebody explain how and why I can't change the size? How can I change the size?
Thank u for help.
EDIT
I tried it with two different cells ("Map Cell" and "listAllBakeries") and now it works with the size.
When I click on an entry there isn't an update at the "Map Cell" but on the "listAllBakeries". More than one Map
The code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//CODE TO BE RUN ON CELL TOUCH
//get the Location with latitude and longitude
var location = CLLocationCoordinate2D(latitude: latitude[indexPath.item], longitude: longitude[indexPath.item])
//resolution
var span = MKCoordinateSpanMake(0.003, 0.003)
var region = MKCoordinateRegion(center: location,span:span)
//here is the mistake
let cell2:ListPlacesTableViewCell = tableView.dequeueReusableCellWithIdentifier("MapCell", forIndexPath: indexPath) as! ListPlacesTableViewCell
//some Text about the Place
var annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = namesBakeries[indexPath.item]
annotation.subtitle = "some Text"
//Zooming inside the map
cell2.Map.setRegion(region, animated: true)
cell2.Map.addAnnotation(annotation)
}
I don't really understand this. I use the right identifier (MapCell) but the section/row is wrong. How can I use the right section?
Here is my code how I fill the rows/section
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(indexPath.section == 0) {
let cell2:ListPlacesTableViewCell = tableView.dequeueReusableCellWithIdentifier("MapCell", forIndexPath: indexPath) as! ListPlacesTableViewCell
//insert MapStuff
//addAnnotations
//MapStuff
return cell2
} else {
//Standard-Labels with text
let cell:ListPlacesTableViewCell = tableView.dequeueReusableCellWithIdentifier("listAllBakeries", forIndexPath: indexPath) as! ListPlacesTableViewCell
cell.nameLabel?.text = namesBakeries[indexPath.row]
cell.adressLabel?.text = "Test 2"
return cell
}
}
Thank for help
(I'm sorry for my english but this isn't my mothertongue).
It looks like your map is above the uiTableView rather than a separate prototype cell in your table.
Set your uiTableView up with 2 prototype cells then put the map in the first.
Then, as you have done, you can test the value of indexpath.row.
Okay I found out.
The trick is to update always the same cell.
I defined an array. Then save my Cell2 in this array and just used this Object to update my map. (My english is awful I know, maybe my code will give more information.)
class ListPlacesTableViewController: UITableViewController {
var constantCell = [ListPlacesTableViewCell?](count: 1, repeatedValue: nil)
....
//other stuff here
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(indexPath.section == 0) {
let cell2:ListPlacesTableViewCell = tableView.dequeueReusableCellWithIdentifier("MapCell", forIndexPath: indexPath) as! ListPlacesTableViewCell
constantCell[0] = cell2
//other stuff here
}
}
//Clickable Cell Function add:
constantCell[0]!.Map.setRegion(region, animated: true)
constantCell[0]!.Map.addAnnotation(annotation)
Thanks for help

Text overlapping itself in table cells SWIFT

I have some text which goes into UIlabels I have created inside a table view cell. When these table view cells become updated the text overlaps itself, almost like the previous text what was there has not been removed, like so:
code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) as! UITableViewCell
var nameLabel = UILabel(frame: CGRectMake(cell.frame.size.width * 0.040, cell.frame.size.height * 0.22, cell.frame.size.width * 0.735, cell.frame.size.height * 0.312))
var userAtIndexPath = finalMatchesBlurUser[indexPath.row]
nameLabel.text = userAtIndexPath.username.uppercaseString
cell.addSubview(nameLabel)
}
The finalMatchesBlurUser is a PFUser fetched from Parses database that will be changing, when this change is what causes the names to overlap.
Can anyone point out why this is happening?
Everytime you update the tableview, it checks the queue to see if it can reuse a cell instead of initializing a new one. In this case, when it updates, it has cells in the queue so you're adding a new label subview everytime the table updates which is causing this effect. In this case, you should only add the label subview if it doesn't exist already. Otherwise, just update the text of that subview.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) as! UITableViewCell
if let nameLabel = cell.viewWithTag(100) as? UILabel{
var userAtIndexPath = finalMatchesBlurUser[indexPath.row]
nameLabel.text = userAtIndexPath.username.uppercaseString
}
else{
nameLabel = UILabel(frame: CGRectMake(cell.frame.size.width * 0.040, cell.frame.size.height * 0.22, cell.frame.size.width * 0.735, cell.frame.size.height * 0.312))
nameLabel.tag = 100;
var userAtIndexPath = finalMatchesBlurUser[indexPath.row]
nameLabel.text = userAtIndexPath.username.uppercaseString
cell.addSubview(nameLabel)
}
return cell;
}
the UILabel is created every time even when the cell is reused.
A solution is to create the UILabel in Interface Builder and assign a tag (e.g. 100).
Then use this code
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) as! UITableViewCell
let nameLabel = cell.viewWithTag(100) as! UILabel
let userAtIndexPath = finalMatchesBlurUser[indexPath.row]
nameLabel.text = userAtIndexPath.username.uppercaseString
}