Reputation: 431
I have a tableView that displays hidden cells when the user scrolls. Not sure why this behavior is happening.
In viewDidLoad()
watchListTable = UITableView(frame: CGRect(x: self.view.frame.width * 0.25, y: 0, width: self.view.frame.width * 0.75, height: 300)) //height = 200
watchListTable.isHidden = true
watchListTableFrame = CGRect(x: self.view.frame.width * 0.25, y: 0, width: self.view.frame.width * 0.75, height: 300)
watchListTableFrameHide = CGRect(x: self.view.frame.width * 0.25, y: 0, width: self.view.frame.width * 0.75, height: 0)
watchListTable.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
watchListTable.register(UITableViewCell.self, forCellReuseIdentifier: "closeCell")
watchListTable.dataSource = self
watchListTable.delegate = self
watchListTable.CheckInterfaceStyle()
watchListTable.roundCorners(corners: .allCorners, radius: 8)
watchListTable.backgroundColor = .systemGray6
//remove the bottom line if there is only one option
watchListTable.tableFooterView = UIView()
view.addSubview(watchListTable)
Once the user taps on a button, the table expands in an animatable fashion.
//watchlist won't animate properly on the initial setup. So we set it to be
hidden, then change the frame to be 0, unhide it, and then animate it. Only will
be hidden on the initial setup.
if(watchListTable.isHidden == true)
{
watchListTable.isHidden = false
watchListTable.frame = watchListTableFrameHide
}
UIView().animateDropDown(dropDown: watchListTable, frames:
self.watchListTableFrame)
watchListTable.reloadData()
In func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if(indexPath.row >= watchListStocks.count)
{
let cell = tableView.dequeueReusableCell(withIdentifier: "closeCell",
for: indexPath as IndexPath)
cell.selectionStyle = .none
cell.textLabel?.text = indexPath.row == watchListStocks.count + 1 ?
"Close List" : "Create New Watchlist"
cell.textLabel?.textColor = .stockOrbitTeal
cell.textLabel?.textAlignment = .center
cell.backgroundColor = .systemGray6
cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right:
.greatestFiniteMagnitude)
return cell
}
else
{
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for:
indexPath as IndexPath)
cell.selectionStyle = .none
if(indexPath.row == 0)
{
cell.layer.cornerRadius = 8
cell.layer.maskedCorners = [.layerMinXMinYCorner,
.layerMaxXMinYCorner]
}
else
{
cell.layer.cornerRadius = 8
cell.layer.maskedCorners = [.layerMinXMaxYCorner,
.layerMaxXMaxYCorner]
cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right:
.greatestFiniteMagnitude)
cell.directionalLayoutMargins = .zero
}
let label = UITextView()
label.frame = CGRect(x: 0, y: 0, width: cell.frame.width * 0.45, height:
cell.frame.height)
label.text = watchListStocks[indexPath.row].listName
label.textColor = .stockOrbitTeal
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 18, weight: UIFont.Weight.medium)
label.backgroundColor = .systemGray5
label.delegate = self
label.tag = indexPath.row
cell.addSubview(label)
cell.backgroundColor = .systemGray5
cell.layer.cornerRadius = 8
return cell
}
When I scroll, all cells are hidden. I see that they are created in cellForRowAt, however, they do not appear on my screen. Why are the cells being hidden? I have searched all over stackoverflow.
Upvotes: 0
Views: 1181
Reputation: 431
So after many hours, I figured it out...
I had called this function in viewDidLoad()
watchListTable.roundCorners(corners: .allCorners, radius: 8)
Which made my table hidden after I scrolled. I removed this line of code, and the table is now completely visible when scrolling.
Upvotes: 2
Reputation: 88437
You shouldn't add subviews inside cellForRowAt
. When you call dequeueReusableCell
, at first it'll create new cells, but when you start scrolling it'll start returning cells that were dismissed earlier, means they already have UITextView
subview, and you're adding one more on top of that.
cell returned by dequeueReusableCell
doesn't have to have final size already, that's why you can't use cell.frame.width
to calculate your subview size, I think that's may be the reason you can't see it.
What you need to do: create a UITableView
subclass, something like this:
class MyCell: UITableViewCell {
let label = UITextView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupCell()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupCell()
}
func setupCell() {
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 18, weight: UIFont.Weight.medium)
label.backgroundColor = .systemGray5
contentView.addSubview(label)
}
override func layoutSubviews() {
super.layoutSubviews()
label.frame = CGRect(x: 0, y: 0, width: contentView.frame.width * 0.45, height: contentView.frame.height)
}
}
Here you're adding a subview during initialisation only once and update label frame each time cell size gets changed. Don't forget to add this class to your cell in the storyboard and let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath) as! MyCell
, so you can set delegate to text field, etc.
If this won't help, check out View Hierarchy to see what's actually going on there
Upvotes: 1