Expand the only tapped cell and collapse other cells - ios

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()
}

Related

UITalbeViewCell is flickering after reloadSection

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)
}

Reordering cells in UITableView takes out functionality of cells in Swift?

I am using JSON to parse data from Spotify and add songs into a UITableView. The songs play fine, and I added functionality for deleting cells, but when adding functionality for reording cells, I can''t play songs and I can't swipe to delete them either. Any ideas would be appreciated.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tableView.isEditing = true
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
This adds the album image and song name to the TableView.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let mainImageView = cell?.viewWithTag(2) as! UIImageView
mainImageView.image = posts[indexPath.row].mainImage
let mainLabel = cell?.viewWithTag(1) as! UILabel
mainLabel.text = posts[indexPath.row].name
return cell!
}
This adds the swipe to delete functionality.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
posts.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.
}
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
This adds the reordering functionality.
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObject = self.posts[sourceIndexPath.row]
posts.remove(at: sourceIndexPath.row)
posts.insert(movedObject, at: destinationIndexPath.row)
debugPrint("\(sourceIndexPath.row) => \(destinationIndexPath.row)")
self.tableView.reloadData()
}
You don't want to set
self.tableView.isEditing = true
in viewDidLoad. This takes you from the "normal" mode where you can select a cell, or other elements in a cell. Setting "self.tableview.isEditing" is the equivalent of hitting an edit button on the top right-hand corner of many tableViews.

UITableView changes scroll position when cell height changes

I have a tableView that expands cell height when user taps on cell. The problem is in some cells after expanding cell height tableView scrolls very higher or lower the selectedCell I mean it miss the current cell position
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if cellsMode[indexPath.row] {
return 344
}
else {
return 140 }
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.cellsMode[indexPath.row] = !self.cellsMode[indexPath.row]
table.reloadData()
}
I tried to use
let indexPath = NSIndexPath(row: cellInex, section: 0)
self.table.scrollToRow(at: indexPath as IndexPath, at: .bottom, animated: false)
but it not worked.
How can i fixed it?
Just reload cell not entire tableview, like bellow:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.cellsMode[indexPath.row] = !self.cellsMode[indexPath.row]
tableView.reloadRows(at: [indexPath], with: .automatic)
}

Can't edit/delete top row in uitableview - Swift

Not sure why but the top row of my uitableview is not editable, all other rows function as normal and delete as expected. It's like caneditrowat indexPath: Indexpath isn't working for that one row. See images attached.
My code in tableView(_:commit:forRowAt:) looks like all the tutorials I can find, can't seem to find any other examples with this problem.
//MARK: Properties
var favouriteExercises = [FavouriteExercise]()
override func viewDidLoad() {
super.viewDidLoad()
//Load exercises from local DB
if let savedFavouriteExercises = loadFavouriteExercises()
{
//loading exercises in from the favourites
favouriteExercises += savedFavouriteExercises
}
// Use the edit button item provided by the table view controller.
navigationItem.rightBarButtonItem = editButtonItem
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//count number of rows in table
return favouriteExercises.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Table view cells are reused and should be dequeued using a cell identifier.
let cellIdentifier = "FavouriteTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? FavouriteTableViewCell else {
fatalError("The dequeued cell is not an instance of FavouriteTableViewCell.")
}
// Fetches the appropriate exercise for the data source layout.
let exercise = favouriteExercises[indexPath.row]
//setup the layout for the cell in the table view
cell.nameLabel.text = exercise.name
let url = URL(string: (exercise.iconUrl))!
cell.photoImageView.sd_setImage(with: url)
//cell.photoImageView.image = #imageLiteral(resourceName: "defaultPhoto")
cell.backgroundColor = UIColor.darkGray
return cell
}
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
favouriteExercises.remove(at: indexPath.row)
saveFavouriteExercisess()
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
Thanks for the help
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle
{
return UITableViewCellEditingStyle.delete
}
Answer adapted from #KumarReddy's solution

Tableview inside another table view with dynamic height for inner tableview

im new to iOS development.The thing im trying to achieve is to have a tableView inside another tableView and must have selection for items in that inner tableView. There are some problems facing when i implemented this.
i need to have a dynamic table view height (ie,for the first time loading ,inner table view should only have a height to show 3 cells and on clicking a show more button in the outer tableview cell ,the outer table view cell will expand and show the remaining cells in the inner table view)
On selecting a cell in the inner tableView, the same cell in the inner table view cell all other cells are also getting selected.
Im attaching the code i did and image of what im trying to achieve.
Please click here to see the desing i want to achieve
Outer Main Table View methods
extension Explore:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 13
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = exploreTableView.dequeueReusableCell(withIdentifier: "exploreCell", for: indexPath) as! ExploreAlbumPosting
if isExpanded{
cell.showMoreBtn.setTitle("Show Less", for: .normal)
cell.showMoreBtn.setImage(#imageLiteral(resourceName: "ic_arrow_drop_up"), for: .normal)
}
else{
cell.showMoreBtn.setTitle("Show More", for: .normal)
cell.showMoreBtn.setImage(#imageLiteral(resourceName: "ic_arrow_drop_down"), for: .normal)
}
cell.showMoreBtn.addTarget(self, action: #selector(showMoreBtnTapped(sender:)), for: .touchUpInside)
cell.showMoreBtn.tag = indexPath.row
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if isExpanded && selectedIndex == indexPath{
return 180 * numberOfRowsInInnerTableView
}
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 215
}
}
show More Btn Tapp action
func showMoreBtnTapped(sender:UIButton){
let row = sender.tag
self.selectedIndex = IndexPath(item: row, section: 0)
isExpanded = !isExpanded
self.exploreTableView.reloadRows(at: [selectedIndex!], with: .automatic)
self.exploreTableView.scrollToRow(at: selectedIndex!, at:UITableViewScrollPosition.middle, animated: true)
}
inner Table view Methods ( This is extended to the customcell class - UITableViewCell of outer table view)
extension ExploreAlbumPosting:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = innerAlbumTableView.dequeueReusableCell(withIdentifier: "ExploreAlbumInnerCell", for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 92
}
}
Please help me.Thank you

Resources