Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
[ad_1]
I am currently developing a Fitness Application and working on Workout View. It has a functionality similar to to-do checklist. So basically the user is marking Sets of a certain exercise that he finished. I know that it is needed to prepare TableViewCells for reuse, and I did that for the state when all the sets of exercise is done and user shouldn’t be able to interact whit that TableViewCell anymore. The only thing that keeps getting duplicated is numberOfRowsInSection. Guys please help me find the missing part, I have been trying for two days at this point:(
TableView is inside the collectionViewCell so I am initializing it from there. I am using custom delegate as I have to have an access to tableView from the view that holds collectionView.
protocol TableViewCellDelegate: AnyObject {
func tableView(tableViewCell: WorkoutStartedTVCurrentExerciseCell, index: Int, didTappedInTableViewCell: WorkoutStartedCell)
// other delegate methods that you can define to perform action in viewcontroller
}
class WorkoutStartedCell: UICollectionViewCell {
weak var cellDelegateTV: TableViewCellDelegate?
let scrollView: UIScrollView = {
let view = UIScrollView()
view.backgroundColor = UIColor.clear
view.isScrollEnabled = true
view.contentMode = .center
view.showsHorizontalScrollIndicator = false
view.isMultipleTouchEnabled = true
view.isUserInteractionEnabled = true
return view
}()
let titleLabel: UILabel = {
let label = UILabel()
label.backgroundColor = UIColor.clear
label.textColor = UIColor.black
label.textAlignment = .center
label.text = "Incline Bench Press"
label.font = UIFont.systemFont(ofSize: 23.0, weight: .semibold)
return label
}()
let numberOfExercisesLabel: UILabel = {
let label = UILabel()
label.backgroundColor = UIColor.clear
label.textColor = UIColor.black.withAlphaComponent(0.7)
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 16.5, weight: .medium)
return label
}()
let container: UIView = {
let view = UIView()
view.layer.cornerRadius = 10
view.backgroundColor = UIColor.black
view.layer.shadowOffset = CGSize(width: 0, height: 0)
view.clipsToBounds = false
view.layer.shadowOpacity = 0.35
view.layer.shadowRadius = 10
view.layer.shadowColor = UIColor.black.cgColor
return view
}()
let tableView: UITableView = {
let tableView = UITableView()
tableView.backgroundColor = UIColor.clear
tableView.separatorStyle = .none
tableView.register(WorkoutStartedTVCurrentExerciseCell.self, forCellReuseIdentifier: "currentExerciseCellID")
tableView.layer.cornerRadius = 0
tableView.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
tableView.showsHorizontalScrollIndicator = false
tableView.showsVerticalScrollIndicator = true
tableView.isScrollEnabled = true
return tableView
}()
var number_of_sets : Int!
var number_of_reps : Int!
var completed_sets = [Int]()
var remaining_sets = [Int]()
//var current_set: IndexPath!
//var completedSets: [Int]!
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.white
contentView.isUserInteractionEnabled = true
isMultipleTouchEnabled = true
//tableView.estimatedRowHeight = 0
//tableView.estimatedSectionHeaderHeight = 0
//tableView.estimatedSectionFooterHeight = 0
//tableView.delegate = self
//tableView.dataSource = self
tableView.isScrollEnabled = false
contentView.addSubview(scrollView)
scrollView.addSubview(titleLabel)
scrollView.addSubview(numberOfExercisesLabel)
scrollView.addSubview(container)
scrollView.addSubview(tableView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: heightAnchor).priority = UILayoutPriority.defaultLow
//scrollView.delegate = self
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 25).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
titleLabel.sizeToFit()
numberOfExercisesLabel.translatesAutoresizingMaskIntoConstraints = false
numberOfExercisesLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10).isActive = true
numberOfExercisesLabel.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
numberOfExercisesLabel.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
numberOfExercisesLabel.sizeToFit()
container.translatesAutoresizingMaskIntoConstraints = false
container.topAnchor.constraint(equalTo: numberOfExercisesLabel.bottomAnchor, constant: 15).isActive = true
container.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0).isActive = true
container.widthAnchor.constraint(equalToConstant: self.frame.width - 0).isActive = true
container.heightAnchor.constraint(equalToConstant: self.frame.width - 0).isActive = true
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: container.bottomAnchor, constant: 20).isActive = true
tableView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
override func prepareForReuse() {
super.prepareForReuse()
number_of_sets = nil
number_of_reps = nil
remaining_sets.removeAll()
completed_sets.removeAll()
tableView.delegate = nil
tableView.dataSource = nil
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension WorkoutStartedCell: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return remaining_sets.count + completed_sets.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "currentExerciseCellID", for: indexPath) as! WorkoutStartedTVCurrentExerciseCell
cell.selectionStyle = .none
cell.Set.text = "\(Array(1...number_of_sets)[indexPath.row])"
cell.Reps.text = "\(number_of_reps ?? 1)"
if completed_sets.count == number_of_sets {
cell.isUserInteractionEnabled = false
} else {
cell.isUserInteractionEnabled = true
}
if completed_sets.contains(where: {$0 == indexPath.row}) == false, indexPath.row == remaining_sets.first {
//Current Set
cell.Set.textColor = #colorLiteral(red: 0, green: 0.9810667634, blue: 0.5736914277, alpha: 1).withAlphaComponent(0.75)
cell.SetStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.Weight.textColor = #colorLiteral(red: 0, green: 0.9810667634, blue: 0.5736914277, alpha: 1).withAlphaComponent(0.75)
cell.WeightStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.Reps.textColor = #colorLiteral(red: 0, green: 0.9810667634, blue: 0.5736914277, alpha: 1).withAlphaComponent(0.75)
cell.RepsStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.CompletedImage.tintColor = UIColor.white
cell.CompletedImage.backgroundColor = UIColor.white
cell.CompletedImage.layer.borderColor = UIColor.darkGray.withAlphaComponent(0.9).cgColor
} else if completed_sets.contains(indexPath.row) == true, remaining_sets.contains(indexPath.row) == false {
//Completed Set
cell.Set.textColor = UIColor.black.withAlphaComponent(0.7)
cell.SetStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.Weight.textColor = UIColor.black.withAlphaComponent(0.7)
cell.WeightStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.Reps.textColor = UIColor.black.withAlphaComponent(0.7)
cell.RepsStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.CompletedImage.tintColor = UIColor.white
cell.CompletedImage.backgroundColor = UIColor.darkGray.withAlphaComponent(0.9)
cell.CompletedImage.layer.borderColor = UIColor.darkGray.withAlphaComponent(0.9).cgColor
} else if completed_sets.contains(indexPath.row) == false, remaining_sets.contains(indexPath.row) == true, indexPath.row != remaining_sets.first {
//Remaining Sets
cell.Set.textColor = UIColor.black.withAlphaComponent(1.0)
cell.SetStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.Weight.textColor = UIColor.black.withAlphaComponent(1.0)
cell.WeightStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.Reps.textColor = UIColor.black.withAlphaComponent(1.0)
cell.RepsStatic.textColor = UIColor.black.withAlphaComponent(0.7)
cell.CompletedImage.tintColor = UIColor.white
cell.CompletedImage.backgroundColor = UIColor.white
cell.CompletedImage.layer.borderColor = UIColor.darkGray.withAlphaComponent(0.9).cgColor
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 75
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as? WorkoutStartedTVCurrentExerciseCell
self.cellDelegateTV?.tableView(tableViewCell: cell!, index: indexPath.row, didTappedInTableViewCell: self)
}
}
Here is how I pass the data from ViewController and setting CollectionView delegate and data source.
`
extension workoutStartedView: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return exercise_names.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let exercisesCount = Array(1...exercise_names.count)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! WorkoutStartedCell
cell.number_of_reps = Int(number_of_reps[indexPath.item])!
cell.number_of_sets = Int(number_of_sets[indexPath.item])!
cell.remaining_sets = remainingSets[indexPath.item]
cell.completed_sets = completedSets[indexPath.item]
cell.titleLabel.text = exercise_names[indexPath.item]
cell.numberOfExercisesLabel.text = "Exercise \(exercisesCount[indexPath.item]) of \(exercise_names.count)"
cell.cellDelegateTV = self
cell.tableView.heightAnchor.constraint(equalToConstant: 75 * CGFloat(Int(self.number_of_sets[indexPath.item])!)).isActive = true
cell.scrollView.contentSize = CGSize(width: collectionView.frame.width, height: 100 + (collectionView.frame.width) + (75 * CGFloat(Int(self.number_of_sets[indexPath.item])!)))
cell.scrollView.scrollToTop(animated: false)
cell.tableView.delegate = cell.self
cell.tableView.dataSource = cell.self
cell.tableView.reloadData()
//cell.layoutIfNeeded()
cell.tag = Array(0...exercise_names.count - 1)[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.scrollToItem(at: indexPath, at: .left, animated: true)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.width - 40, height: collectionView.bounds.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
}
`
Here I am handling data from collectionViewCell throw custom delegate
`
extension workoutStartedView: TableViewCellDelegate {
func tableView(tableViewCell: WorkoutStartedTVCurrentExerciseCell, index: Int, didTappedInTableViewCell: WorkoutStartedCell) {
//if didTappedInTableViewCell.remaining_sets.count > 1 {
didTappedInTableViewCell.completed_sets.append(didTappedInTableViewCell.remaining_sets.first!)
didTappedInTableViewCell.remaining_sets.removeFirst()
if completedSets.count > 0 {
if self.completedSets.count > didTappedInTableViewCell.tag {
self.completedSets[didTappedInTableViewCell.tag] = didTappedInTableViewCell.completed_sets
} else if self.completedSets.count <= didTappedInTableViewCell.tag {
self.completedSets.append(didTappedInTableViewCell.completed_sets)
}
} else if completedSets.count <= 0 {
self.completedSets.append(didTappedInTableViewCell.completed_sets)
}
if self.remainingSets[didTappedInTableViewCell.tag].count > 0 {
self.remainingSets[didTappedInTableViewCell.tag] = didTappedInTableViewCell.remaining_sets
} else if self.remainingSets[didTappedInTableViewCell.tag].count <= 1 {
self.remainingSets.removeFirst()
}
print(didTappedInTableViewCell.completed_sets)
print(didTappedInTableViewCell.remaining_sets)
print(self.completedSets)
print(self.remainingSets)
//collectionView.reloadData()
didTappedInTableViewCell.tableView.reloadData()
}
}
`
[ad_2]