I have some problems with reloading section in tableView. If the cell is hiding a bit on the top, it becomes flicking. If the cell is fully visible, everything works fine. The height of cell is fixed, and it's not automaticDimension. All of cells are standard UITableViewCell with different background color. I know that tableView is a very common UI element in ios, and I hope someone had faced the same problem before. Thanks!
func numberOfSections(in tableView: UITableView) -> Int {
return contactsForSections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let contact = contactsForSections[section]
return contact.isExpanded ? contact.numbers.count : 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = UITableViewCell()
cell.contentView.backgroundColor = .green
return cell
} else {
let cell = UITableViewCell()
cell.contentView.backgroundColor = .red
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard indexPath.row == 0 else { return }
contactsForSections[indexPath.section].isExpanded.toggle()
tableView.reloadSections([indexPath.section], with: .none)
}
Related
I am doing expand/collapse when tapped on tableview cell, but I have to close all other cells except the tapped one. Tried this solution Expand only the cell that has been tapped this solution is not working for me.
below code which I have written for expand/collapse
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datasource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView .dequeueReusableCell(withIdentifier: String(describing: ExpandingTableViewCell.self), for: indexPath) as! ExpandingTableViewCell
cell.set(content: datasource[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let content = datasource[indexPath.row]
content.expanded = !content.expanded
tableView.reloadRows(at: [indexPath], with: .automatic)
}
You need to collapse all cells and change the current clicked one state , then reload all the table
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let current = datasource[indexPath.row].expanded
datasource.forEach { $0.expanded = false }
let content = datasource[indexPath.row]
content.expanded = !current
tableView.reloadData()
}
My custom cell don't appear in my table View and I didn't find anything to answer that.
Here's my storyboard that contains the TableView :
This is my listController :
extension MatchListViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MatchCell", for: indexPath) as? MatchTableViewCell else {
return UITableViewCell()
}
let match = matchArray[indexPath.row]
cell.configure(nomDuMatch: match.matchName, scoreFinal: match.finalScore)
return cell
}
}
(I've configured the dataSourceDelegate by storyboard)
the customCell identifier is correct and I really don't understand why nothing appears at launch..
Feel free to ask me more pictures / infos !
Edit :
This is the result :
You need to implement
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100 // or any value
}
or use automatic cell and set constraints properly in IB as it seems that you have a constraints problem and set this in viewDidLoad
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
I use two tableView with 5 and 3 cells over scrollview . Trying to use swipeable gesture on both tableView using editActionsForRowAt method of tableView But it just swipe only three cells of first tableView and other cell swipe by trying 5 to 7 times or unswipeable. Help me to get it ,
Thanks in advance
my code
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == table1{
return 5
}
else if tableView == table2{
return 3
}
else{
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == table1{
let cell = meetingTable.dequeueReusableCell(withIdentifier: "myCell") as! meetingCell
cell.cell_name.text = "abc"
cell.cell_copny.text = "08276"
return cell
}
else{
let cell = followTable.dequeueReusableCell(withIdentifier: "myCell") as! FollowUpCell
cell.cell_name.text = "abc"
cell.cell_phone.text = "134135"
return cell
}
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let Btn1 = UITableViewRowAction(style: .normal, title: "\u{1F4DE}\n Btn1") { action, index in
//code
}
Btn1.backgroundColor = UIColor.lightGray
let Btn2 = UITableViewRowAction(style: .normal, title: "\u{1F4D3}\n Btn2") { action, index in
//code
}
Btn2.backgroundColor = UIColor.orange
return [Btn2,Btn1]
}
I'm calling a TableView inside of a custom ViewController. In my UITableView, my cells overlap. Like so
In the storyboard editor, I have the Row Height set to Custom at 63pts, but they look like they're actually using the the default height that the cell would be if you unchecked the Custom box.
Like in some of the other solutions tried implementing the heightForRowAt function but it doesn't do anything. I've tried using obscenely large numbers, but the result is always exactly as it was before.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if(self.view.traitCollection.horizontalSizeClass == .compact ||
self.view.traitCollection.verticalSizeClass == .compact) {
cellHeight = 55
return 55
}
else{
return 63
}
}
The only thing in solutions I've seen so far that looks at all promising is this one. iOS UITableViewCell overlapping
I've tried implementing the prepareForReuse Function in my custom TableViewCell class file, but I didn't know what I was actually supposed to add to the function, so I just called the super function and added a print statement
--- Full TableView Code ---
extension SavingViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "WishlistTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? WishlistTableViewCell else {
fatalError("The dequeued cell is not an instance of WishlistTableViewCell.")
}
cell.selectionStyle = .none
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if(self.view.traitCollection.horizontalSizeClass == .compact ||
self.view.traitCollection.verticalSizeClass == .compact) {
cellHeight = 55
return 55
}
else{
return 63
}
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
/*
let resultRemoving = bookmarks[indexPath.row]
if var bookmarkData = defaults.object(forKey:"bookmarkDict") as? [String: [String]] {
bookmarkData.removeValue(forKey: resultRemoving.resultURL)
defaults.set(bookmarkData, forKey:"bookmarkDict")
}
defaults.synchronize()
*/
items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
}
Currently heightForRowAt is not being called since heightForRowAt method is a UITableViewDelegate method so
Your extension should look like this:
Add UITableViewDelegate
extension SavingViewController: UITableViewDataSource, UITableViewDelegate {
}
how to set background color of the cells which are selected on section tableview
every section or genre should have single selected cell only enter image description here
SEE Image description PLZ
I know how to select single cell in table view but here I wanted for every section only one select cell
this my code
var sections = [
Sections(genre: "🦁 Animation",
movies: ["The Lion King", "The Incredibles"],
expanded: false),
Sections(genre: "💥 Superhero",
movies: ["Guardians of the Galaxy", "The Flash", "The Avengers", "The Dark Knight"],
expanded: false),
Sections(genre:"👻 Horror",
movies: ["The Walking Dead", "Insidious", "Conjuring"],
expanded: false)
]
override func viewDidLoad() {
super.viewDidLoad()
// 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 numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].movies.count
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if(sections[indexPath.section].expanded){
return 44
}else{
return 0
}
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 2
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = ExpandableHeaderView()
header.customInit(title: sections[section].genre, section: section, delegate: self)
return header
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "labelCell")!
cell.textLabel?.text = sections[indexPath.section].movies[indexPath.row]
return cell
}
////////////
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
//let cell = tableView.dequeueReusableCell(withIdentifier: "labelCell")!
cell?.contentView.backgroundColor = UIColor.red
//cell?.backgroundColor = UIColor.red
}
func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
//let cell = tableView.dequeueReusableCell(withIdentifier: "labelCell")!
cell?.contentView.backgroundColor = UIColor.white
//cell?.backgroundColor = UIColor.blue
}
////////////
func toggleSection(header: ExpandableHeaderView, section: Int) {
sections[section].expanded = !sections[section].expanded
tableView.beginUpdates()
for i in 0 ..< sections[section].movies.count{
tableView.reloadRows(at: [IndexPath(row: i , section: section)], with: .automatic)
}
tableView.endUpdates()
}
What you can do is a complete use of the delegate functions provided by the table view:
Inside func tableView(UITableView, didSelectRowAt: IndexPath) you can check the section and row that has been selected. You will also need to check a constant check on the var indexPathsForSelectedRows: [IndexPath]? array that this returns.
Now that you have a. the current selection b. the list of seelections,
you can go ahead and delete/add data into your final array as required.
So in your case, inside func tableView(UITableView, didSelectRowAt: IndexPath) you will check if the indexPathsForSelectedRows has the section+row count already. If it does, then simply play with the highlighting in the tableView: UITableView, didHighlightRowAt indexPath: IndexPath) and then change the array that stores the list of selected movies accordingly. If not simply add it.