Why 'edit actions' are not appear ,but (_:editActionsForRowAt) is called - ios

When I am swiping left, edit actions do not appear. But! All delegete's functions called (canEditRowAt and editActionsForRowAt) Why I can not swipe?
import UIKit
class HikingCustomLocationViewController: UIViewController {
//MARK: - Constants
private let DEFAULT_HEADER_FOOTER_VIEW_ID = "DefaultHeaderFooterViewId"
private let CUSTOM_LOCATION_CELL_ID = "CustomLocationCellId"
// MARK: - UI properties
private lazy var customLocationTableView: UITableView = {
let tableView = UITableView()
tableView.backgroundColor = ColorHelper.bckgDefaultBlue
tableView.separatorStyle = .singleLine
tableView.separatorColor = ColorHelper.bckgDefaultBlue
tableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
tableView.indicatorStyle = .white
tableView.backgroundColor = ColorHelper.bckgDefaultBlue
tableView.isHidden = true
// Delagates
tableView.delegate = self
tableView.dataSource = self
// Registration
let defaultHeaderFooterViewNib = UINib(nibName: "DefaultTableViewHeaderFooterView", bundle: nil)
tableView.register(defaultHeaderFooterViewNib, forHeaderFooterViewReuseIdentifier: DEFAULT_HEADER_FOOTER_VIEW_ID)
let customLocationViewCellNib = UINib(nibName: "PlacesTableViewCell", bundle: nil)
tableView.register(customLocationViewCellNib, forCellReuseIdentifier: CUSTOM_LOCATION_CELL_ID)
return tableView
}()
private lazy var userMessageLabel: UILabel = {
let label = UILabel()
label.font = FontHelper.body
label.textAlignment = .center
label.numberOfLines = 0
label.textColor = ColorHelper.bckgTextTextWhite
label.text = NSLocalizedString("PLACESNOTHINGADDED", comment: "")
label.isHidden = true
return label
}()
// MARK: - Dependencies
private lazy var messageBus = MessageBus.sharedInstance
private lazy var globalState = GlobalState.sharedInstance
// MARK: - Props
enum HikingCustomLocationProps {
case loading
case loaded(customLocationGroups: [(tourId: String, customLocations: [CustomLocation])])
}
private var props: HikingCustomLocationProps = .loading {
didSet {
view.setNeedsLayout()
}
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
switch props {
case .loading:
customLocationTableView.isHidden = true
userMessageLabel.isHidden = true
case .loaded(let customLocationGroups):
if customLocationGroups.isEmpty {
customLocationTableView.isHidden = true
userMessageLabel.isHidden = false
} else {
customLocationTableView.isHidden = false
userMessageLabel.isHidden = true
}
customLocationTableView.reloadData()
}
}
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
title = NSLocalizedString("PLACESTITLE", comment: "")
view.backgroundColor = ColorHelper.bckgDefaultBlue
setupMessageBusDelegates()
subscribeMessages()
view.addSubview(customLocationTableView)
view.addSubview(userMessageLabel)
setupConstraints()
if case .product(let appStoreId) = globalState.state {
messageBus.send(msg: GetCustomLocationsAction(appStoreId: appStoreId))
}
}
deinit {
unsubscribeMessages()
}
// MARK: - MessageBus
private var customLocationsReadyMessage: MessageBusDelegate<CustomLocationsReadyMessage>?
private func setupMessageBusDelegates() {
customLocationsReadyMessage = MessageBusDelegate<CustomLocationsReadyMessage>(closure: { [weak self] msg in
if case .product(let appStoreId) = self?.globalState.state {
if msg.appStoreId != appStoreId { return }
self?.props = .loaded(customLocationGroups: msg.customLocationsGroup)
}
if case .tour(let appStoreId, _, _) = self?.globalState.state {
if msg.appStoreId != appStoreId { return }
self?.props = .loaded(customLocationGroups: msg.customLocationsGroup)
}
})
}
private func subscribeMessages() {
messageBus.subscribe(closure: customLocationsReadyMessage)
}
private func unsubscribeMessages() {
messageBus.unsubscribe(closure: customLocationsReadyMessage)
}
// MARK: - Constraints
private func setupConstraints() {
customLocationTableView.translatesAutoresizingMaskIntoConstraints = false
customLocationTableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
customLocationTableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
customLocationTableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
customLocationTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
userMessageLabel.translatesAutoresizingMaskIntoConstraints = false
userMessageLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
userMessageLabel.widthAnchor.constraint(equalToConstant: 288).isActive = true
userMessageLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16).isActive = true
}
}
// MARK: - UITableViewDelegate
extension HikingCustomLocationViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if case .loaded(let customLocationGroups) = props {
guard
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: DEFAULT_HEADER_FOOTER_VIEW_ID) as? DefaultTableViewHeaderFooterView,
let group = customLocationGroups[safe: section]
else { return nil }
headerView.configure(title: ("\(NSLocalizedString("TOUR", comment: "")) \(group.tourId)"), description: nil)
headerView.contentView.backgroundColor = ColorHelper.bckgTableHeaderDarkBlue
return headerView
}
return nil
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if case .product(let appStoreId) = globalState.state {
if case .loaded(let customLocationGroups) = props {
guard
let group = customLocationGroups[safe: indexPath.section],
let cLocation = group.customLocations[safe: indexPath.row],
let tourId = Int(group.tourId)
else { return }
globalState.state = .tour(
appStoreId: appStoreId,
tourId: tourId,
mapSelectionState: .customLocation(id: cLocation.id))
let hikingTourContainerVC = HikingTourContainerViewController(
exitButtonTitile: NSLocalizedString("PLACESTITLE", comment: ""))
self.navigationController?.pushViewController(hikingTourContainerVC, animated: true)
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
if case .loaded(let customLocationGroups) = props {
return customLocationGroups.count
}
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if case .loaded(let customLocationGroups) = props {
guard let customLocations = customLocationGroups[safe: section] else { return 0 }
return customLocations.customLocations.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if case .loaded(let customLocationGroups) = props {
guard
let customLocations = customLocationGroups[safe: indexPath.section]?.customLocations,
let cell = tableView.dequeueReusableCell(withIdentifier: CUSTOM_LOCATION_CELL_ID) as? PlacesTableViewCell,
let cLocation = customLocations[safe: indexPath.row]
else { return UITableViewCell() }
cell.configure(noteText: cLocation.note, date: cLocation.date)
setSelectedBackgroundViewFor(cell)
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction(style: .destructive, title: NSLocalizedString("DELETE", comment: ""), handler: { (rowAction, indexPath) in
print("Delete action")
})
return [deleteAction]
}
private func setSelectedBackgroundViewFor(_ cell: UITableViewCell) {
let selectedBackgroundView = UIView()
selectedBackgroundView.backgroundColor = ColorHelper.bckg3DefalutBlue
cell.selectedBackgroundView = selectedBackgroundView
}
}

The problem was in calling customLocationTableView.reloadData() inside viewWillLayoutSubviews(). After moving it out, (In my case, I move it to props' didSet) edit actions start to appear.

Related

Swift5 Get the "invalid number of rows in section" error when trying to delete a row in tableview (task manager with core data)

Trying to create the Task manager App with core data. I have an array with all done and current tasks. I divide it for two arrays to load a tableview (it shows either current tasks or tasks are done). When I'm trying to delete a task with swipe on the table, I receive "invalid number of rows in section" error. My code is below. Please advise how to fix it? My thanks in advance.
import UIKit
import Foundation
protocol TaskNotesDelegate: AnyObject {
func refreshTasks()
func deleteTask(with id: UUID)
}
class TasksViewController: UIViewController {
#IBOutlet weak var doneTaskSwitcher: UIBarButtonItem!
#IBOutlet weak var addTaskButton: UIBarButtonItem!
static let identifier = "TasksViewController"
let tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
return tableView
}()
let idTasksCell = "idTasksCell"
//константа для реализации функции поиска через searc controllr
let searchController = UISearchController(searchResultsController: nil)
var allTasks: [Task] = []
var doneTasks: [Task] = []
var currentTask: [Task] = []
private var filteredTasks: [Task] = []
var currentSearch = ""
var doneTasksCheck = false
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
tableView.register(TaskTableViewCell.self, forCellReuseIdentifier: idTasksCell)
configureSearchBar()
setConstraints()
fetchTasksFromStorage()
for i in 0..<allTasks.count {
if allTasks[i].taskIsDone {
doneTasks.append(allTasks[i])
} else {
currentTask.append(allTasks[i])
}
}
for i in 0..<allTasks.count {
print("all \(allTasks[i].id)")
}
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.backgroundColor = .white
self.tabBarController?.tabBar.backgroundColor = .white
tableView.reloadData()
}
#IBAction func showDoneTasks(_ sender: UIBarButtonItem) {
if doneTasksCheck == false {
doneTasksCheck = true
doneTaskSwitcher.title = "current"
doneTasks = doneTasks.sorted { $0.taskDate > $1.taskDate }
tableView.reloadData()
addTaskButton.isEnabled = false
} else {
doneTasksCheck = false
doneTaskSwitcher.title = "is done"
tableView.reloadData()
addTaskButton.isEnabled = true
}
}
private func indexForTask(id: UUID, in list: [Task]) -> IndexPath {
let row = Int(list.firstIndex(where: { $0.id == id }) ?? 0)
return IndexPath(row: row, section: 0)
}
#IBAction func addTaskButton(_ sender: UIBarButtonItem) {
goToEditTask(createTask())
}
private func goToEditTask(_ task: Task) {
let controller = storyboard?.instantiateViewController(identifier: TaskDetailsViewController.identifier) as! TaskDetailsViewController
controller.task = task
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)
}
// MARK:- Methods to implement
private func createTask() -> Task {
let task = CoreDataManager.shared.createTask()
// Update table
allTasks.insert(task, at: 0)
tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
return task
}
private func fetchTasksFromStorage() {
allTasks = CoreDataManager.shared.fetchTasks()
}
private func deleteTaskFromStorage(_ task: Task) {
deleteTaskSviped(with: task.id)
CoreDataManager.shared.deleteTask(task)
}
}
//UITableViewDelegate, UITableViewDataSource
extension TasksViewController: UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if doneTasksCheck == true {
if currentSearch == "" {
filteredTasks = doneTasks.sorted { $0.taskDate > $1.taskDate }
}
} else {
if currentSearch == "" {
filteredTasks = currentTask.sorted { $0.taskDate < $1.taskDate }
}
}
return filteredTasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: idTasksCell, for: indexPath) as! TaskTableViewCell
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd.MM.YYYY"
cell.taskLabel.text = filteredTasks[indexPath.row].task
cell.taskDateLabel.text = dateFormatter.string(from: filteredTasks[indexPath.row].taskDate)
if filteredTasks[indexPath.row].taskDate < Date().onlyDate! {
cell.taskDateLabel.textColor = .red
} else {
cell.taskDateLabel.textColor = .black
}
cell.taskTegLabel.text = filteredTasks[indexPath.row].taskTag
if filteredTasks[indexPath.row].taskReminder != nil {
cell.taskRemindTimeLabel.isHidden = false
dateFormatter.dateFormat = "HH:mm"
cell.taskRemindTimeLabel.text = dateFormatter.string(from: filteredTasks[indexPath.row].taskReminder!)
} else {
cell.taskRemindTimeLabel.isHidden = true
}
if filteredTasks[indexPath.row].taskNote == nil || filteredTasks[indexPath.row].taskNote == "" {
cell.taskNoteLabel.isHidden = true
} else {
cell.taskNoteLabel.isHidden = false
}
if filteredTasks[indexPath.row].taskIsDone == false {
cell.taskDoneButton.setBackgroundImage(UIImage(systemName: "circle"), for: .normal)
} else {
cell.taskDoneButton.setBackgroundImage(UIImage(systemName: "chevron.down.circle.fill"), for: .normal)
}
cell.layer.masksToBounds = true
cell.layer.cornerRadius = 15
cell.layer.borderWidth = 2
cell.layer.borderColor = UIColor.white.cgColor
cell.selectionStyle = .none
cell.cellTaskDelegate = self
cell.index = indexPath
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 75
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
goToEditTask(filteredTasks[indexPath.row])
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
deleteTaskFromStorage(filteredTasks[indexPath.row])
}
}
}
extension TasksViewController {
func setConstraints() {
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
])
}
}
// MARK:- TaskNotes Delegate
extension TasksViewController: TaskNotesDelegate {
func refreshTasks() {
allTasks = allTasks.sorted { $0.taskDate < $1.taskDate }
currentTask = currentTask.sorted { $0.taskDate < $1.taskDate }
tableView.reloadData()
}
func deleteTaskSviped(with id: UUID) {
let indexPath = indexForTask(id: id, in: filteredTasks)
filteredTasks.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
// just so that it doesn't come back when we search from the array
allTasks.remove(at: indexForTask(id: id, in: allTasks).row)
}
}

Swift- Using Delegation to append data to TableView within CollectionView

I have a CollectionViewController named yearOnethat looks something like this:
When you click the add button for each quarter cell it leads you to SearchPage:
I used delegation to append the data clicked on SearchPage to yearOne
The delegation seems to work and data seems to append as I tried the print(vc.data) but it doesn't seem to show up on the tableView when backed into yearOne viewcontroller through navigationController?.popViewController(animated: true) Am I doing something wrong?
import UIKit
class yearOne: UICollectionViewController, coursesDelegate {
let customCellIdentifier = "cellID"
let customCellIdentifier2 = "cellID2"
let customCellIdentifier3 = "cellID3"
let customCellIdentifier4 = "cellID4"
let quarters = [
customLabel (title: "Fall Quarter"),
customLabel (title: "Winter Quarter"),
customLabel (title: "Spring Quarter"),
customLabel (title: "Summer Quarter")
]
let vc = fallQuarterCell()
let vc2 = winterQuarterCell()
let vc3 = springQuarterCell()
let vc4 = summerQuarterCell()
func sendDataBackFall(data: String) {
vc.data.append(data)
print(vc.data)
//UserDefaults.standard.set(vc.data, forKey: "SavedArray")
}
func sendDataBackWinter(data2: String) {
vc2.data.append(data2)
}
func sendDataBackSpring(data3: String) {
vc3.data.append(data3)
}
func sendDataBackSummer(data4: String) {
vc4.data.append(data4)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
vc.tableView.reloadData()
collectionView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
self.collectionView!.register(fallQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier)//
self.collectionView!.register(winterQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier2)
self.collectionView!.register(springQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier3)
self.collectionView!.register(summerQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier4)
navigationItem.title = "Year One"
navigationController?.navigationBar.prefersLargeTitles = true
collectionView?.backgroundColor = .lightGray
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return quarters.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (indexPath.row == 0){
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier, for: indexPath) as! fallQuarterCell
cell1.layer.borderColor = UIColor.orange.cgColor
cell1.layer.borderWidth = 2
cell1.layer.cornerRadius = 5
cell1.quarters = self.quarters[0]
return cell1
}
else if (indexPath.row == 1){
let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier2, for: indexPath) as! winterQuarterCell
cell2.layer.borderColor = UIColor.blue.cgColor
cell2.layer.borderWidth = 2
cell2.layer.cornerRadius = 5
cell2.quarters = self.quarters[1]
return cell2
}
else if (indexPath.row == 2){
let cell3 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier3, for: indexPath) as! springQuarterCell
cell3.layer.borderColor = UIColor.green.cgColor
cell3.layer.borderWidth = 2
cell3.layer.cornerRadius = 5
cell3.quarters = self.quarters[2]
return cell3
}
else if (indexPath.row == 3){
let cell4 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier4, for: indexPath) as! summerQuarterCell
cell4.layer.borderColor = UIColor.red.cgColor
cell4.layer.cornerRadius = 5
cell4.quarters = self.quarters[3]
return cell4
}
else{
return UICollectionViewCell()
}
}
#objc func buttonAction(sender: UIButton!) {
switch sender.tag {
case 0:
let destination = SearchPage()
destination.delegate = self
destination.tag = sender.tag
navigationController?.pushViewController(destination, animated: true)
case 1:
let destination = SearchPage()
destination.delegate = self
destination.tag = sender.tag
navigationController?.pushViewController(destination, animated: true)
case 2:
let destination = SearchPage()
destination.delegate = self
destination.tag = sender.tag
navigationController?.pushViewController(destination, animated: true)
case 3:
let destination = SearchPage()
destination.delegate = self
destination.tag = sender.tag
navigationController?.pushViewController(destination, animated: true)
default:
let destination = SearchPage()
destination.delegate = self
destination.tag = sender.tag
navigationController?.pushViewController(destination, animated: true)
}
}
}
extension yearOne : UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (view.frame.width - 30)
return CGSize(width: width, height: 200)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 8
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
UIEdgeInsets(top: 30, left: 10, bottom: 30, right: 10)
}
}
class fallQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {
//var data = UserDefaults.standard.object(forKey: "SavedArray") as? [String] ?? [String]()
var data : [String] = []
// func load(){
// if let loadeddata: [String] = UserDefaults.standard.object(forKey: "SavedArray") as? [String] {
// data = loadeddata
// tableView.reloadData()
// }
// }
let cellId = "coursesName"
let tableView:UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = UIColor.white
return tableView
}()
override init(frame: CGRect){
super.init(frame: frame)
addSubview(tableView)
setupView()
}
func setupView(){
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
tableView.delegate = self
tableView.dataSource = self
self.backgroundColor = UIColor.white
contentView.addSubview(quarterLabel)
contentView.addSubview(addButton)
quarterLabel.translatesAutoresizingMaskIntoConstraints = false
quarterLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
quarterLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
addButton.translatesAutoresizingMaskIntoConstraints = false
addButton.topAnchor.constraint(equalTo: quarterLabel.topAnchor, constant: -5).isActive = true
addButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
addButton.heightAnchor.constraint(equalToConstant: 25).isActive = true
addButton.widthAnchor.constraint(equalToConstant: 25).isActive = true
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 35).isActive = true
tableView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5).isActive = true
tableView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
tableView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
if (indexPath.row == 0){
data.remove(at: 0)
//UserDefaults.standard.set(data, forKey: "SavedArray")
self.tableView.reloadData()
}
else if (indexPath.row == 1){
data.remove(at: 1)
//UserDefaults.standard.set(data, forKey: "SavedArray")
self.tableView.reloadData()
}
else if (indexPath.row == 2){
data.remove(at: 2)
//UserDefaults.standard.set(data, forKey: "SavedArray")
self.tableView.reloadData()
}
else if (indexPath.row == 3){
data.remove(at: 3)
//UserDefaults.standard.set(data, forKey: "SavedArray")
self.tableView.reloadData()
}
else if (indexPath.row == 4){
data.remove(at: 4)
//UserDefaults.standard.set(data, forKey: "SavedArray")
self.tableView.reloadData()
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//add class information???
}
var quarters: customLabel? {
didSet {
guard let quarters = quarters else {return}
quarterLabel.text = quarters.title
}
}
let quarterLabel : UILabel = {
let label = UILabel()//frame: CGRect(x: 15, y: -75, width: 300, height: 50))
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.black
label.font = UIFont.boldSystemFont(ofSize: 16)
//label.textAlignment = .center
return label
}()
let addButton : UIButton = {
let button = UIButton()//frame: CGRect(x: 345, y: 10, width: 30, height: 30))
button.setImage(UIImage(named: "addicon"), for: .normal)
button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
button.tag = 0
button.addTarget(self, action: #selector(yearOne.buttonAction), for: .touchUpInside)
return button
}()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I also have the
class winterQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource
class springQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource
class summerQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource
similar to fallQuarterCell but excluded it.
import UIKit
protocol coursesDelegate {
func sendDataBackFall(data: String)
func sendDataBackWinter(data2: String)
func sendDataBackSpring(data3: String)
func sendDataBackSummer(data4: String)
}
class SearchPage: UITableViewController {
var delegate: coursesDelegate?
let cellId = "course"
var allCourses : NSArray = NSArray()
var filteredCourses = [String]()
var resultSearchController = UISearchController()
var tag: Int?
let vc = fallQuarterCell()
let vc2 = winterQuarterCell()
let vc3 = springQuarterCell()
let vc4 = summerQuarterCell()
override func viewDidLoad() {
super.viewDidLoad()
let courses : CourseList = CourseList()
allCourses = courses.coursesList
navigationItem.title = "Select Courses"
navigationController?.navigationBar.prefersLargeTitles = true
//let button1 = UIBarButtonItem(title: "Add Course", style: .plain, target: self, action: #selector(addTapped))
//self.navigationItem.rightBarButtonItem = button1
self.view.backgroundColor = .systemBackground
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
tableView.delegate = self
tableView.dataSource = self
self.tableView.tableFooterView = UIView()
resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.obscuresBackgroundDuringPresentation = false
controller.searchBar.placeholder = "Search Courses"
controller.searchBar.sizeToFit()
tableView.tableHeaderView = controller.searchBar
return controller
})()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (resultSearchController.isActive) {
return filteredCourses.count
}
else{
return allCourses.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
if (resultSearchController.isActive) {
cell.textLabel?.text = filteredCourses[indexPath.row]
return cell
}
else {
let courses = self.allCourses[indexPath.row]
cell.textLabel?.text = courses as? String
return cell
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
tableView.deselectRow(at: indexPath, animated: true)
if (tag == 0){
if (resultSearchController.isActive){
// vc.data.append(filteredCourses[indexPath.row])
// UserDefaults.standard.set(vc.data, forKey: "SavedArray")
// self.navigationController?.popViewController(animated: true)
let data = filteredCourses[indexPath.row]
delegate?.sendDataBackFall(data: data)
self.navigationController?.popViewController(animated: true)
}
else{
// vc.data.append(allCourses[indexPath.row] as! String)
// UserDefaults.standard.set(vc.data, forKey: "SavedArray")
// self.navigationController?.popViewController(animated: true)
let data = allCourses[indexPath.row] as! String
delegate?.sendDataBackFall(data: data)
self.navigationController?.popViewController(animated: true)
}
}
else if (tag == 1){
if (resultSearchController.isActive){
// vc2.data.append(filteredCourses[indexPath.row])
// UserDefaults.standard.set(vc2.data, forKey: "SavedArray2")
// self.navigationController?.popViewController(animated: true)
let data = filteredCourses[indexPath.row]
delegate?.sendDataBackWinter(data2: data)
self.navigationController?.popViewController(animated: true)
}
else{
// vc2.data.append(allCourses[indexPath.row] as! String)
// UserDefaults.standard.set(vc2.data, forKey: "SavedArray2")
// self.navigationController?.popViewController(animated: true)
let data = allCourses[indexPath.row] as! String
delegate?.sendDataBackWinter(data2: data)
self.navigationController?.popViewController(animated: true)
}
}
else if (tag == 2){
if (resultSearchController.isActive){
// vc3.data.append(filteredCourses[indexPath.row])
// UserDefaults.standard.set(vc3.data, forKey: "SavedArray3")
// self.navigationController?.popViewController(animated: true)
}
else{
// vc3.data.append(allCourses[indexPath.row] as! String)
// UserDefaults.standard.set(vc3.data, forKey: "SavedArray3")
// self.navigationController?.popViewController(animated: true)
}
}
else if (tag == 3){
if (resultSearchController.isActive){
// vc4.data.append(filteredCourses[indexPath.row])
// UserDefaults.standard.set(vc4.data, forKey: "SavedArray4")
// self.navigationController?.popViewController(animated: true)
}
else{
// vc4.data.append(allCourses[indexPath.row] as! String)
// UserDefaults.standard.set(vc4.data, forKey: "SavedArray4")
// self.navigationController?.popViewController(animated: true)
}
}
}
var isSearchBarEmpty: Bool {
return resultSearchController.searchBar.text?.isEmpty ?? true
}
}
extension SearchPage: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filteredCourses.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (allCourses as NSArray).filtered(using: searchPredicate)
filteredCourses = array as! [String]
self.tableView.reloadData()
}
}
I commented out the UsersDefault.standard.set.... because the data itself doesn't seem to refresh and display in the tableView atm
Check at your cellForRow method. I don't believe you set the text anywhere.

How to remove extra space from table view of style- grouped?

Yes I have already tried these from other similar questions but they didn't work:
var frame = CGRect.zero
frame.size.height = .leastNormalMagnitude
tableView.tableHeaderView = UIView(frame: frame)
and
self.automaticallyAdjustsScrollViewInsets = false;
definesPresentationContext = true
Have a look at the extra space I am trying to remove below search bar:
Screenshot
Maybe you can point out an improvement in my code for the same:
import UIKit
class SelectCountryViewController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {
struct CellStruct
{
var countryName : String
var countryFlag : String
var countryDialCode : String
}
var cellDatas = [CellStruct]()
var filteredCellDatas = [CellStruct]()
var searchController : UISearchController!
var resultsController = UITableViewController()
var refreshController = UIRefreshControl()
var searchTextField : UITextField!
var searchLoaded = false
var isSearching = false
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self;
var frame = CGRect.zero
frame.size.height = .leastNormalMagnitude
tableView.tableHeaderView = UIView(frame: frame)
self.automaticallyAdjustsScrollViewInsets = false;
//tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
definesPresentationContext = true
configureSearchController()
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancel))
navigationItem.leftBarButtonItem = cancelButton
//self.navigationItem.title = "Select Country"
let searchButton: UIBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: #selector(searchButtonAction))
searchButton.image = UIImage(named: "search")
self.navigationItem.rightBarButtonItem = searchButton
refreshController.attributedTitle = NSAttributedString(string: "")
refreshController.addTarget(self, action: #selector(refreshSelector), for: .valueChanged)
tableView.addSubview(refreshController)
guard let path = Bundle.main.path(forResource: "countries", ofType: "json")
else
{
return
}
let url = URL(fileURLWithPath: path)
do
{
let data = try Data (contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
print(json)
guard let array = json as? [Any] else { return}
for info in array {
guard let userDict = info as? [String: Any] else { return}
guard let code = userDict["code"] as? String else { print("No code found"); return}
guard let dialCode = userDict["dial_code"] as? String else { print("No dial code found"); return}
guard let name = userDict["name"] as? String else { print("No name found"); return}
print("We have: ", code, dialCode, name)
cellDatas.append(CellStruct(countryName: name, countryFlag: code, countryDialCode: dialCode))
}
}
catch
{
print(error)
}
}
func configureSearchController()
{
resultsController.tableView.delegate = self
resultsController.tableView.dataSource = self
self.searchController = UISearchController(searchResultsController: self.resultsController)
//self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self
self.searchController.searchBar.scopeButtonTitles = []
for subView in searchController.searchBar.subviews {
for subViewOne in subView.subviews {
if subViewOne is UITextField {
searchTextField = subViewOne as! UITextField
subViewOne.backgroundColor = UIColor.white
break
}
}
}
self.automaticallyAdjustsScrollViewInsets = false;
extendedLayoutIncludesOpaqueBars = true
definesPresentationContext = true
}
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
// tableView.setContentOffset(self.navigationItem, animated: true)
searchController.searchBar.barTintColor = UIColor.white
//searchController.searchBar.layer.borderColor = UIColor.white.cgColor
searchTextField.backgroundColor = UIColor.searchBarTextFieldGrey()
return true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
self.searchController.searchBar.showsCancelButton = false
// searchController.searchBar.barTintColor = nil
searchTextField.backgroundColor = UIColor.white
searchController.searchBar.barTintColor = nil
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.backIndicatorImage = nil
}
func updateSearchResults(for searchController: UISearchController) {
//tableView.separatorStyle = UITableViewCellSeparatorStyle.none
if searchController.searchBar.text! == "" {
filteredCellDatas = cellDatas
} else {
// Filter the results
filteredCellDatas = cellDatas.filter { $0.countryName.lowercased().contains(searchController.searchBar.text!.lowercased()) }
}
resultsController.tableView.reloadData()
// tableView.separatorStyle = .none
// tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == resultsController.tableView
{
isSearching = true
return filteredCellDatas.count
}
else
{
isSearching = false
return cellDatas.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
cell?.separatorInset.left = 15
if cell == nil {
cell = UITableViewCell(style: .value1, reuseIdentifier: "Cell")
cell?.separatorInset.left = 0
}
if tableView == resultsController.tableView
{
cell?.textLabel?.text = filteredCellDatas[indexPath.row].countryName
cell?.detailTextLabel?.text = filteredCellDatas[indexPath.row].countryDialCode
cell?.imageView?.image = UIImage (named: filteredCellDatas[indexPath.row].countryFlag)
}
else
{
cell?.textLabel?.text = cellDatas[indexPath.row].countryName
cell?.detailTextLabel?.text = cellDatas[indexPath.row].countryDialCode
cell?.imageView?.image = UIImage (named: cellDatas[indexPath.row].countryFlag)
}
cell?.textLabel?.textColor = UIColor.labelGray2()
cell?.detailTextLabel?.textColor = UIColor.labelGray2()
cell?.textLabel?.font = UIFont(name:"SF Pro Text", size:15)
cell?.detailTextLabel?.font = UIFont(name:"SF Pro Text", size:15)
return cell!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.row, indexPath.section)
// let currentCell = tableView.cellForRow(at: indexPath)
if(isSearching)
{
print(filteredCellDatas[indexPath.row].countryFlag)
UserDefaults.standard.set(filteredCellDatas[indexPath.row].countryFlag, forKey: "preferredCountry")
if searchController.isActive {
DispatchQueue.main.async {
self.searchController.dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "unWindFromSelectCountry", sender: nil)
})
}
} else {
// Play segue, dismiss or pop ...
self.performSegue(withIdentifier: "unWindFromSelectCountry", sender: nil)
}
}
else
{
print(cellDatas[indexPath.row].countryFlag)
UserDefaults.standard.set(cellDatas[indexPath.row].countryFlag, forKey: "preferredCountry")
self.performSegue(withIdentifier: "unWindFromSelectCountry", sender: nil)
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return CGFloat.leastNormalMagnitude
}
return tableView.sectionHeaderHeight
}
#objc func cancel(){
navigationController?.popViewController(animated: true)
}
#objc func refreshSelector()
{
if(!searchLoaded)
{
searchLoaded = true
self.tableView.tableHeaderView = searchController.searchBar
print( "Got ya")
}
refreshController.endRefreshing()
}
#objc func searchButtonAction() {
if(!searchLoaded)
{
searchLoaded = true
self.tableView.tableHeaderView = searchController.searchBar
// self.navigationItem.titleView = searchController.searchBar
}
self.searchController.searchBar.becomeFirstResponder()
self.searchController.searchBar.text = ""
// self.navigationItem.rightBarButtonItem = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
As said the table view is of style grouped. I am configuring search bar from code. And updating results therefore using code in the same table view.
Thanks in advance
Maybe it is not a tableHeaderView I presume that it could be particular Section HeaderView try with this:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return CGFloat.leastNormalMagnitude
}
return tableView.sectionHeaderHeight
}
Code is hiding header for first section in the table

Random grey bar appears on top of ViewController in iOS (swift)

I am making an app currently and on the main screen where I load multiple items from Parse, I see a weird grey bar. I don't know where this bar came from as it does not show up on the storyboard and I don't know how to fix it. It never was a problem until it randomly recently showed up. Here is the code for that ViewController.
import UIKit
import Parse
import ParseUI
import Kingfisher
class HomeTableViewController: PFQueryTableViewController
{
override func viewDidLoad ()
{
super.viewDidLoad()
setTitle()
self.navigationController?.isNavigationBarHidden = true
self.navigationController?.navigationBar.setHeight(0.0)
// self.tableView.scrollsToTop = true
// self.tableView.scrollToNearestSelectedRow(at: UITableViewScrollPosition.bottom, animated: false)
// self.tableView.scrollToNearestSelectedRow(at: UITableViewScrollPosition.top, animated: true)
}
func setTitle()
{
var parentView = self.parent
while parent != nil
{
if let menu = parentView as? CucuMenuController
{
// menu.setTitleForLabel("Cucus")
menu.setTitleForLabel("")
break
}
parentView = parentView?.parent
}
}
var firstTime = true
var totalArticles = 0
let appDel = UIApplication.shared.delegate as! AppDelegate
required init!(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
setupHomefeed()
}
func setupHomefeed()
{
// This runs before didFinishLoadingWithOptions
self.parseClassName = "Article"
self.pullToRefreshEnabled = true
self.paginationEnabled = true
self.objectsPerPage = 10
self.loadingViewEnabled = true
}
override func objectsDidLoad(_ error: Error?)
{
super.objectsDidLoad(error)
if firstTime
{
firstTime = false
self.loadObjects()
self.tableView.reloadData()
}
else
{
PFObject.pinAll(inBackground: self.objects)
}
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
override func viewDidAppear(_ animated: Bool)
{
navigationController?.isNavigationBarHidden = false
if PFUser.current() == nil || PFUser.current()!["name"] == nil
{
let viewController = storyboard!.instantiateViewController(withIdentifier: "LoginController")
UIApplication.shared.keyWindow?.rootViewController = viewController
}
else if UserDefaults.standard.bool(forKey: "showDemo")
{
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
else
{
self.loadObjects()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if self.objects!.count < totalArticles && self.objects!.count > 0
{
return self.objects!.count + 1
}
return self.objects!.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.row == self.objects?.count
{
return 70.0
}
else
{
return 221.5
}
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.0
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
if indexPath.row == self.objects!.count
{
return tableView.dequeueReusableCell(withIdentifier: "loadCell") as UITableViewCell!
}
if (indexPath.row > self.objects!.count)
{
return cell!
}
let imageView = cell?.viewWithTag(200) as! UIImageView
let titleText = cell?.viewWithTag(101) as! UILabel
let timeLabel = cell?.viewWithTag(102) as! UILabel
let newImage = cell?.viewWithTag(100) as! UIImageView
let diffImage = cell?.viewWithTag(300) as! UIImageView
let scoreLabel = cell?.viewWithTag(301) as! UILabel
let catLabel = cell?.viewWithTag(103) as! UILabel
let article = Article(parseData: self.objects![indexPath.row])
titleText.text = article.title
timeLabel.text = article.duration
catLabel.text = article.category.uppercased()
let hasRead = UserController.hasReadArticle(article.objectId)
newImage.isHidden = hasRead
if hasRead
{
let score = UserController.getScoreForArticle(article.objectId)
scoreLabel.text = NSString(format: "YOUR SCORE: %.0f", score) as String
var performance = "hard"
if score >= article.idealScore { performance = "easy" }
else if score * 2 >= article.idealScore { performance = "medium" }
diffImage.image = UIImage(named: performance + "ScoreTag")
if UserController.getPlayableForArticle(article.objectId) {
cell?.isUserInteractionEnabled = true
}
}
else
{
scoreLabel.text = NSString(format: "AVG. SCORE: %.0f", article.idealScore) as String
diffImage.image = UIImage(named: article.difficulty.lowercased() + "ScoreTag")
}
//Image
let resource = ImageResource(downloadURL: article.getImageURL(), cacheKey: article.objectId)
imageView.kf.setImage(with: resource)
UIHelper.addShadowToHomeCell((cell?.viewWithTag(1)!)!)
return cell!
}
var selectedIndex = -1
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if indexPath.row == self.objects!.count
{
self.loadNextPage()
}
else
{
selectedIndex = indexPath.row
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "detailSegue"
{
let dest = segue.destination as? ArticlePreviewViewController
if UserDefaults.standard.bool(forKey: "showDemo")
{
dest?.article = DemoArticle().article
}
else
{
dest?.article = Article(parseData: self.objects![selectedIndex])
}
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "CUCU_START"), object: nil)
}
override func queryForTable() -> PFQuery<PFObject>
{
let q = PFQuery(className: "Article").whereKey("releaseDate", lessThanOrEqualTo: Date()).whereKey("validated", equalTo: true)
if firstTime
{
q.fromLocalDatastore()
}
else
{
let mods = PFQuery(className: "Question").whereKey("article", matchesQuery: q)
mods.findObjectsInBackground
{
(objects, err) -> Void in
PFObject.pinAll(inBackground: objects)
}
}
print(firstTime)
totalArticles = q.countObjects(nil)
q.order(byDescending: "createdAt")
return q
}
}
Here are a few images of what the problem looks like:
Edit 1:
As suggested in the comments, I even tried to debug view hierarchy but I don't know which element to delete to make the grey bar go away.
It looks like it might be your navigation bar. Have you tried using this:
self.navigationController?.setNavigationBarHidden(true, animated: true)
instead of the statement you have of:
self.navigationController?.isNavigationBarHidden = true
Update #2:
Actually, I just realized you have that in the viewDidLoad. Move that to viewWillAppear and I bet it will work.
Update #3:
Just to reflect the true fix here, the offending code was in the viewDidAppear:
navigationController?.isNavigationBarHidden = false

UITableView Custom cell data mismatched on fast scrolling

class CalenderCell: UITableViewCell {
#IBOutlet var lblDay: UILabel!
#IBOutlet var lblRest: UILabel!
#IBOutlet var imgCompleted: UIImageView!
override func awakeFromNib()
{
super.awakeFromNib()
}
func updateCell(exerciseobject : Exercise)
{
let resttext = NSLocalizedString("restday", comment: "")
let day = NSLocalizedString("day", comment: "")
let dayexercise = "\(day) \(exerciseobject.exerciseDayID)"
if !exerciseobject.exerciseRestDay
{
lblDay.text = dayexercise
if exerciseobject.exerciseDayStatus
{
imgCompleted.isHidden = false
}
else
{
imgCompleted.isHidden = true
}
lblRest.isHidden = true
}
else
{
lblDay.isHidden = true
imgCompleted.isHidden = true
lblRest.text = resttext
viewWithTag(100)?.backgroundColor = UIColor(red:1.00, green:0.21, blue:0.28, alpha:1.0)
}
}
}
The above is my custom cell class and the below is my tableview class.
When I try to build the app everything is working perfect but whenever I fast scroll the data is mismatching or same data appering in more cells.
I tried:
prepareforreuse()
{
//clearing label and images here
}
in my custom cell class but still getting the fast scrollview data mismatch
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if let cell = calenderTable.dequeueReusableCell(withIdentifier: "CalenderCell", for: indexPath) as? CalenderCell
{
cell.updateCell(exerciseobject: days[indexPath.row])
return cell
}
else
{
return UITableViewCell()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return days.count
}
Either use prepareForReuse and reset your controls to default values or make sure to update all the state for every path in the updateCell method.
e.g.
func updateCell(exerciseobject : Exercise)
{
let resttext = NSLocalizedString("restday", comment: "")
let day = NSLocalizedString("day", comment: "")
let dayexercise = "\(day) \(exerciseobject.exerciseDayID)"
if !exerciseobject.exerciseRestDay
{
lblDay.text = dayexercise
lblDay.isHidden = false
if exerciseobject.exerciseDayStatus
{
imgCompleted.isHidden = false
}
else
{
imgCompleted.isHidden = true
}
lblRest.isHidden = true
viewWithTag(100)?.backgroundColor = nil
}
else
{
lblDay.isHidden = true
imgCompleted.isHidden = true
lblRest.text = resttext
lblRest.isHidden = false
viewWithTag(100)?.backgroundColor = UIColor(red:1.00, green:0.21, blue:0.28, alpha:1.0)
}
}

Resources