Before duplicating this question, please be known that I've spent days on this issue, working hours, and looking for all same sort of questions on SO, but there is something I am missing or doing wrong.
I have a tableView in which the data is being populated via API response. Below is the model I have.
struct Model : Codable {
let bugClassification : [Bug]?
}
struct Bug : Codable {
let selectable : String? //Telling wether cell is single/Multi selected
var options : [Options]?
}
struct Options : Codable, Equatable {
let title : String?
let id: Int
var isCellSelected: Bool = false
}
Scenario
I want to create multiple sections, each having different cell depending upon the type of selectable, either single or multi. I have achieved that, but the problem I am getting is that whenever I scroll, random cells are also selected. Now, I know this behaviour is because of tableView reusing the cells. But I am confused as how to handle all this. Also, I want to put the validation on the sections, that is, every section should have atleast one cell selected. Kindly guide me in the right direction, and any small help would be appreciated. Below is my code.
CellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if bugClassification[indexPath.section].selectable?.lowercased() == "multi-select" {
//Multi-Selection
let cell = tableView.dequeueReusableCell(withIdentifier: multiSelectionCellID) as! MultiSelectionCell
let item = bugClassification[indexPath.section].options![indexPath.row]
cell.label.text = item.title
if item.isCellSelected {
cell.checkMarkImageView.alpha = 1
cell.checkMarkView.layer.borderColor = UIColor.white.cgColor
cell.checkMarkView.backgroundColor = .emerald
} else if item.isCellSelected {
cell.checkMarkImageView.alpha = 0
cell.checkMarkView.layer.borderColor = UIColor.veryLightBlue.cgColor
cell.checkMarkView.backgroundColor = .white
}
return cell
} else {
//Single-Selection
let cell = tableView.dequeueReusableCell(withIdentifier: singleSelectionCellID) as! SingleSelectionCell
let item = bugClassification[indexPath.section].options![indexPath.row]
cell.label.text = item.title
if item.isCellSelected {
cell.checkMarkImageView.alpha = 1
cell.checkMarkView.layer.borderColor = UIColor.emerald.cgColor
} else {
cell.checkMarkImageView.alpha = 0
cell.checkMarkView.layer.borderColor = UIColor.veryLightBlue.cgColor
}
return cell
}
}
DidSelectRow Method
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if bugClassification[indexPath.section].selectable?.lowercased() == "multi-select" {
var item = bugClassification[indexPath.section].options![indexPath.row]
item.isCellSelected = !item.isCellSelected
bugClassification[indexPath.section].options![indexPath.row] = item
self.tableView.reloadRows(at: [indexPath], with: .automatic)
} else {
let items = bugClassification[indexPath.section].options
if let selectedItemIndex = items!.indices.first(where: { items![$0].isCellSelected }) {
bugClassification[indexPath.section].options![selectedItemIndex].isCellSelected = false
if selectedItemIndex != indexPath.row {
bugClassification[indexPath.section].options![indexPath.row].isCellSelected = true
}
} else {
bugClassification[indexPath.section].options![indexPath.row].isCellSelected = true
}
self.tableView.reloadSections([indexPath.section], with: .automatic)
}
}
In cellForRowAt
if item.isCellSelected == true{
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
and update the model by every selection
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let item = bugClassification[indexPath.section].options![indexPath.row]
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
if indexPath.section == 0{
item.isCellSelected.isSelected = false
}else{
item.isCellSelected.isSelected = false
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = bugClassification[indexPath.section].options![indexPath.row]
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
if indexPath.section == 0{
item.isCellSelected.isSelected = true
}else{
item.isCellSelected.isSelected = true
}
}
}
I have UITableView with multiple UITableViewCell, every cell have a different design and high, the problem I have that now the method tableView(cellForRowAtIndexPath) look so weird and unreadable and I don't know if this is the true and the good practice implementation for the case.
My method :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(indexPath.section == 0){ // linked news item
let cellIdentifier = "linkedNewsTableViewCell";
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! LinkedNewsTableViewCell;
let linked_news = LinkedNews[indexPath.row];
cell.newTitle.text = linked_news.news_title;
return cell;
}else if(indexPath.section > 1 && indexPath.row == 0 && indexPath.section != sections.count+2){ // section header item
let cellIdentifier = "sectionHeaderTableViewCell";
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SectionHeaderTableViewCell;
let sec = sections[indexPath.section-2];
cell.lblSectionTitle.text = sec.section_name;
cell.backgroundColor = Constants.Colors.lightGray;
return cell;
}else if(indexPath.section == 2+sections.count){ // all rights reserved item
let cellIdentifier = "allRightsReservedTableViewCell";
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AllRightsReservedTableViewCell;
cell.backgroundColor = Constants.Colors.lightGray;
return cell;
}else if(indexPath.section == 1){ // slider news item
let cellIdentifier = "newsTableViewCell";
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NewsTableViewCell;
cell.imgVideo.hidden = true;
let newsItem = SliderNews[indexPath.row];
cell.txtNews.text = newsItem.news_title;
cell.lblTime.text = Utilities.timeAgoSinceDate(NSDate(timeIntervalSince1970:newsItem.createdstamp!), numericDates: false);
do{
let isSaved = try DBManger.sharedInstance.isSaved(String(newsItem.news_id!));
cell.isSaved = isSaved;
cell.news = newsItem;
if(isSaved == true){
cell.btnSave.setImage(UIImage(named: "ic_bookmark_blue"), forState: .Normal);
}else{
cell.btnSave.setImage(UIImage(named: "ic_bookmark"), forState: .Normal);
}
}catch{
}
if(SliderNews.count-1 == indexPath.row){
cell.buttomLine.hidden = true;
}else{
cell.buttomLine.hidden = false;
}
let image = cell.imgNews.getImage(newsItem.image!, timestamp: String(newsItem.createdstamp!), size: "228", qualty: "70");
cell.imgNews.loadImage(image,contentMode: .ScaleToFill)
cell.lblType.text = newsItem.section_name;
cell.backgroundColor = Constants.Colors.lightGray;
return cell;
}else{ // section news item
let sec = sections[indexPath.section-2];
if(indexPath.row == sec.news.count+1){
let cellIdentifier = "moreNewsTableViewCell";
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MoreNewsTableViewCell;
cell.lblSectionName.text = "المزيد من \(sec.section_name!)";
cell.backgroundColor = Constants.Colors.lightGray;
return cell;
}
let cellIdentifier = "newsTableViewCell";
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NewsTableViewCell;
cell.imgVideo.hidden = true;
let newsItem = sec.news[indexPath.row-1];
cell.txtNews.text = newsItem.news_title;
cell.lblTime.text = Utilities.timeAgoSinceDate(NSDate(timeIntervalSince1970:newsItem.createdstamp!), numericDates: false);
cell.lblType.text = sec.section_name;
if(sec.news.count == indexPath.row){
cell.buttomLine.hidden = true;
}else{
cell.buttomLine.hidden = false;
}
let image = cell.imgNews.getImage(newsItem.image!, timestamp: String(newsItem.createdstamp!), size: "228", qualty: "70");
cell.imgNews.loadImage(image,contentMode: .ScaleToFill)
cell.backgroundColor = Constants.Colors.lightGray;
do{
let isSaved = try DBManger.sharedInstance.isSaved(String(newsItem.news_id!));
cell.isSaved = isSaved;
cell.news = newsItem;
if(isSaved == true){
cell.btnSave.setImage(UIImage(named: "ic_bookmark_blue"), forState: .Normal);
}else{
cell.btnSave.setImage(UIImage(named: "ic_bookmark"), forState: .Normal);
}
}catch{
}
return cell;
}
}
After playing around with your code, you have a few issues thats needs to be resolved before the code can look much better:
1. You need a model that reflects your tableView data source , it should look something like:
let currentSectionModel = self.sections[indexPath.section]
let currentRowModel = currentSectionModel[]
and then you can use something more generic with your cells to set the model object:
cell.setRowModel(currentRowModel)
2. Your if statements that decides witch section to present, are very complicated,
for example this line:
if indexPath.section > 1 && indexPath.row == 0 && indexPath.section != sections.count+2 {
You have to find a better logic for this. Once you orgenize the model like I sad in section 1, This should look much more clear and you can change it to a switch statement, that questions an enum.
3. All cell logic, I prefer to do Inside the cell itself, for cleaner viewController, I've done so at the example code at the end.
4. Don't use strings for identifier, It can cause bugs. that's the reason I prefer to use an extension on UITableViewCell witch returns the class name as the identifier.
5. Don't use semi columns is swift.
6. All your cells should have a base class, that way you can use polymorphism when returning cells.
7. Once you have a model that represent the data source, you can use Switch statement instead of if statement.
This is the example code I've written, you have to work on your code a bit before it will compile. I'ts just a better practice example. (I didn't use switch statements only because your cases are too complexed to use a simple enum. Like I sad, I'ts something you have to work on, and make it more simple)
class BaseCellType: UITableViewCell {
}
class AllRightsReservedTableViewCell: BaseCellType {
// Your implementation
}
class LinkedNewsTableViewCell: BaseCellType {
func setLinkedNews(linedNews: LinkedNews) {
// Your implementation
}
}
class SectionHeaderTableViewCell: BaseCellType {
func setSectionModel(sectionModel: SectionModel) {
// Your implementation
}
}
class MoreNewsTableViewCell: BaseCellType {
func setSection(section: SectionModel) {
// Your implementation
}
}
class NewsTableViewCell: BaseCellType {
// Your implementation
}
class SectionsModel {
let rows: [RowModel]
}
extension UITableViewCell {
static var cellIdentifer: String {
get {
return String(self.dynamicType).componentsSeparatedByString("__").last!
}
}
}
enum SectionType: Int {
case AllRightsReserevedSection = 1, LinkedNewItem = 0
}
class ViewController: UIViewController {
var sections: [SectionsModel]!
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: BaseCellType
switch (section: indexPath.section,row: indexPath.row) {
case (SectionType.AllRightsReserevedSection.rawValue, _):
cell = tableView.dequeueReusableCellWithIdentifier(AllRightsReservedTableViewCell.cellIdentifer, forIndexPath: indexPath) as! AllRightsReservedTableViewCell;
case (SectionType.LinkedNewItem.rawValue, _):
cell = tableView.dequeueReusableCellWithIdentifier(LinkedNewsTableViewCell.cellIdentifer, forIndexPath: indexPath) as! LinkedNewsTableViewCell;
cell.setLinkedNews(LinkedNews[indexPath.row])
case let index where index.section > 1 , index.row == 0, index.section != secrion+2:
cell = tableView.dequeueReusableCellWithIdentifier(SectionHeaderTableViewCell.cellIdentifer, forIndexPath: indexPath) as! SectionHeaderTableViewCell
cell.setSectionModel(sections[indexPath.section-2])
case let index where index.section == section.count + 2:
cell = tableView.dequeueReusableCellWithIdentifier(AllRightsReservedTableViewCell.cellIdentifer, forIndexPath: indexPath) as! AllRightsReservedTableViewCell;
case let index where index.row == (sec.news.count + 1) :
cell = tableView.dequeueReusableCellWithIdentifier(MoreNewsTableViewCell.cellIdentifer, forIndexPath: indexPath) as! MoreNewsTableViewCell;
cell.setSection(sections[indexPath.section-2])
default:
cell = tableView.dequeueReusableCellWithIdentifier(NewsTableViewCell.cellIdentifer, forIndexPath: indexPath) as! NewsTableViewCell;
cell.setNewsItem(sec.news[indexPath.row-1])
}
}
return cell
}
Try this one
func makeBasicTableCell(title:String,details:String,indexPath:NSIndexPath) -> CustomHeaderCell{
let cell = tableProfile.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomHeaderCell
cell.titleLable.text = title
cell.detLable.text = details
return cell
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var tblCell: UITableViewCell!
tableView.registerNib(UINib(nibName: "profile_details", bundle: nil), forCellReuseIdentifier: "cell")
if indexPath.section == 0 {
switch(indexPath.row) {
case 0:
return makeBasicTableCell("Text1", details: "TextDetail1", indexPath: indexPath)
case 1:
return makeBasicTableCell("Text2", details: "TextDetail2", indexPath: indexPath)
case 2:
return makeBasicTableCell("Text3", details: "TextDetail3", indexPath: indexPath)
case 3:
return makeBasicTableCell("Text4", details: "TextDetail4", indexPath: indexPath)
default:
return makeBasicTableCell("", details: "", indexPath: indexPath)
}
} else if indexPath.section == 1 {
switch(indexPath.row) {
case 0:
return makeBasicTableCell("Text5", details: "TextDetail5", indexPath: indexPath)
case 1:
return makeBasicTableCell("Text6", details: "TextDetail6", indexPath: indexPath)
case 2:
return makeBasicTableCell("Text7", details: "TextDetail7", indexPath: indexPath)
default:
return makeBasicTableCell("", details: "", indexPath: indexPath)
}
}
return tblCell
}
In your cellForRowAtIndexPath -> *Objective-C
if(your first condition){
static NSString *cellIdentifier = #"cell";
MANewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
tableView.rowHeight=30;
}else if(second condition ){
static NSString *cellIdentifier = #"cell1";
MANewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
tableView.rowHeight=40;
}else
{
static NSString *cellIdentifier = #"cell2";
MANewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
tableView.rowHeight=50;
}
I hope I help you.
I have a Collection View and a button at the top and that button goes through a list of days. For each day, the collection view should be different and I keep track of changes in a dictionary. However, at each press of the button, I want to reload the data, but it's selecting random cells. When data is reloaded, does it run the cellforitematindexpath over again; if not what exactly does it run?
Here's my CellForItem code:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("availability", forIndexPath: indexPath) as! AvailabilityCell
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
cell.timeInterval.text = timeIntervals[indexPath.row]
cell.timePeriod.text = timesForIntervals[indexPath.row]
cell.timeInterval.textColor = DARK_BLUE
cell.timePeriod.textColor = DARK_BLUE
cell.backView.layer.cornerRadius = 10
cell.backView.layer.masksToBounds = true
cell.backView.layer.borderColor = DARK_BLUE.CGColor
cell.backView.layer.borderWidth = 1
cell.selected = false
if (tempList[indexPath.row] == 1) {
cell.timeInterval.textColor = UIColor.whiteColor()
cell.backView.backgroundColor = DARK_BLUE
cell.timePeriod.textColor = UIColor.whiteColor()
}
return cell
}
Here's my Cell Did Select/Deselect:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! AvailabilityCell
cell.timeInterval.textColor = UIColor.whiteColor()
cell.backView.backgroundColor = DARK_BLUE
cell.timePeriod.textColor = UIColor.whiteColor()
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
tempList[indexPath.row] = 1
self.availability[self.days[index]] = tempList
}
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! AvailabilityCell
cell.timeInterval.textColor = DARK_BLUE
cell.backView.backgroundColor = UIColor.whiteColor()
cell.timePeriod.textColor = DARK_BLUE
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
tempList[indexPath.row] = 0
self.availability[self.days[index]] = tempList
}
Here's where data is reloaded:
#IBAction func decreaseDay(sender: AnyObject) {
index--
day.text = days[index]
dispatch_async(dispatch_get_main_queue()) {
self.timeCollection.reloadData()
}
if (index == 0) {
back.enabled = false
}
forward.enabled = true
}
Here's a view of what's happening:
How it starts:
When I reload:
I believe you should change the swift collection view to reload the page on the left hand corner. The data is reloaded to select the most prioritized item in the download list. Hope this helps!
I am using Parse to store users who have videos and then display their videos in a PFQueryTableViewController (subclasses UITableViewController I believe). I want only the video that is in the TableViewCell which is completely visible to automatically play but I'm having difficulty making the right video play. I looked for solutions but everything was in Objective-C, and my attempts to use the solutions in Swift were unsuccessful. Here is my code:
override func scrollViewDidScroll(scrollView: UIScrollView) {
var cells = self.tableView.visibleCells()
var indexPaths = self.tableView.indexPathsForVisibleRows()!
if (cells.count == 1) {
self.checkVisibilityOfCell(cells[0] as! UsersTableViewCell, forIndexPath: indexPaths[0] as! NSIndexPath)
} else if (cells.count == 2) {
self.checkVisibilityOfCell(cells[1] as! UsersTableViewCell, forIndexPath: indexPaths[1] as! NSIndexPath)
} else if (cells.count > 2) {
for i in 1...(cells.count - 1) {
(cells[i] as! UsersTableViewCell).completelyVisible = true
}
}
}
func checkVisibilityOfCell(cell : UsersTableViewCell, forIndexPath : NSIndexPath){
var cellRect : CGRect = self.tableView.rectForRowAtIndexPath(forIndexPath)
cellRect = self.tableView.superview!.convertRect(cellRect, fromView: self.tableView)
var completelyVisible : Bool = self.tableView.frame.contains(cellRect)
cell.completelyVisible = completelyVisible
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell : UsersTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as? UsersTableViewCell
if(cell == nil) {
cell = UsersTableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: cellIdentifier)
}
if let pfObject = object {
let otherUser = pfObject as! PFUser
cell?.userDisplayed = otherUser
if (cell?.completelyVisible == true) {
// Video playing
println("\(cell?.userDisplayed!.username!) is completely visible")
var video1 = pfObject["video1"] as? PFFile
let video1URL = NSURL(string: (video1?.url)!)
objMoviePlayerController = MPMoviePlayerController(contentURL: video1URL)
objMoviePlayerController.movieSourceType = MPMovieSourceType.Unknown
objMoviePlayerController.view.frame = (cell?.userVideo1.bounds)!
objMoviePlayerController.scalingMode = MPMovieScalingMode.AspectFit
objMoviePlayerController.controlStyle = MPMovieControlStyle.None
objMoviePlayerController.repeatMode = MPMovieRepeatMode.One
objMoviePlayerController.shouldAutoplay = true
cell?.userVideo1.addSubview(objMoviePlayerController.view)
objMoviePlayerController.prepareToPlay()
objMoviePlayerController.play()
} else {
println("\(cell?.userDisplayed!.username!) is not completely visible")
}
}
return cell
}
Since some videos do play, I suspect that one or both of the functions scrollViewDidScroll or checkVisibilityOfCell is incorrect. Any help would be appreciated!
I am trying to update my table cell accessory type when I tap a cell.
here is the code:
var selectedCellArray :[FriendTableViewCell] = []
var friends: [PFUser] = []
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedCell = self.tableView(tableView, cellForRowAtIndexPath: indexPath) as FriendTableViewCell
if (selectedCell.accessoryType == UITableViewCellAccessoryType.None){
selectedCell.accessoryType = .Checkmark
selectedCellArray.append(selectedCell)
}else if (selectedCell.accessoryType == UITableViewCellAccessoryType.Checkmark){
selectedCell.accessoryType = .None
var index = 0
for cell in selectedCellArray{
if (cell != selectedCell){
index++
}else{
break
}
}
selectedCellArray.removeAtIndex(index)
}
self.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
and
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("friend") as? FriendTableViewCell ?? FriendTableViewCell()
var round = 0
var friend: AnyObject = self.friends[indexPath.row]
cell.firstNameLabel.text = friend["firstName"] as? String
cell.lastNameLabel.text = friend["lastName"] as? String
println(selectedCellArray)
round++
var hasFound = false
if (self.checkSelectedArray(selectedCellArray, target: cell)){
cell.accessoryType = .Checkmark
}else{
cell.accessoryType = .None
}
cell.firstNameLabel.sizeToFit()
cell.lastNameLabel.sizeToFit()
return cell
}
func checkSelectedArray(selectedArray:[FriendTableViewCell], target:FriendTableViewCell) -> Bool{
for cell in selectedCellArray{
if cell.isEqual(target){
return true
}
}
return false
}
Also, is there a built-in method like array.contain? Currently, I wrote a function by myself to check if an array has certain element......
Please help me out... I am stuck for this problem for about 8 hours
Storing the reference to the cell isn't a valid strategy as cells can be re-used when the table scrolls. You can't use the current cell accessory to indicate selection state for the same reason.
You can use an NSIndexSet or a Swift dictionary. Here is an implementation using a dictionary -
var selectedCells :Dictionary<String,PFUser>()
var friends: [PFUser] = []
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell = tableView.cellForRowAtIndexPath(indexPath) as FriendTableViewCell
let objectId=friends[indexPath.row].objectId
if (selectedCells[objectId] != nil){
selectedCell.accessoryType = .None
selectedCells.removeValueForKey(objectId)
} else
selectedCell.accessoryType = .Checkmark
selectedCells[objectId]=friends[indexPath.row]
}
tableView.deselectRowAtIndexPath(indexPath, animated:false)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("friend") as? FriendTableViewCell ?? FriendTableViewCell()
var round = 0
var friend: AnyObject = self.friends[indexPath.row]
cell.firstNameLabel.text = friend["firstName"] as? String
cell.lastNameLabel.text = friend["lastName"] as? String
if (selectedCells[friend.objectId] != nil){
selectedCell.accessoryType = .Checkmark
} else
selectedCell.accessoryType = .None
}
cell.firstNameLabel.sizeToFit()
cell.lastNameLabel.sizeToFit()
return cell
}