I'm pretty new here and I'm still trying to figure out the nuances of swift, so please bear with me.
So I'm well aware that a Class cannot subclass more than once class, so how would I go about subclassing a cocoapod SwipeTableViewController as well as CollapsableTableViewController if I'm already subclassing UIViewController?
My second question is, why is the keyboard not presenting itself when I click on the textfield to name my workout? I tried using the textField.becomeFirstResponder(), but that didn't do anything for me. Any suggestions? I also have a pickerview in the same view as the textfield, could that have something to do with my issue?
Any help would be much appreciated!
import UIKit
import RealmSwift
import SwipeCellKit
import CollapsibleTableSectionViewController
class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate, CollapsibleTableSectionDelegate {
let realm = try! Realm()
var workouts : Results<Workouts>?
var days : Results<WeekDays>!
var daysOfWeek : [String] = ["Monday", "Tuesday", "Wednsday", "Thursday", "Friday", "Saturday", "Sunday"]
let picker = UIPickerView()
@IBOutlet weak var WorkoutsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
WorkoutsTableView.delegate = self
WorkoutsTableView.dataSource = self
print(Realm.Configuration.defaultConfiguration.fileURL)
picker.delegate = self
picker.dataSource = self
loadCategories()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
tableView.rowHeight = 80.0
//Populate based on the # of workouts in each day.
let day = days[section]
return day.workouts.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return days[section].day
}
func numberOfSections(in tableView: UITableView) -> Int {
return days.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SwipeTableViewCell
cell.delegate = self
if (days?[indexPath.row]) != nil {
cell.accessoryType = .disclosureIndicator
//Populate with titles of workouts based on section/day of the week.
//cell.textLabel?.text = days?[indexPath.row].workouts[indexPath.row].name
cell.textLabel?.text = days[indexPath.section].workouts[indexPath.row].name
}
return cell
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
self.updateModel(at: indexPath)
}
// customize the action appearance
deleteAction.image = UIImage(named: "delete-icon")
return [deleteAction]
}
func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
var options = SwipeOptions()
options.expansionStyle = .destructive
return options
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
@IBAction func AddWorkoutButton(_ sender: UIButton) {
var textField = UITextField()
let alert = UIAlertController(title: "New Workout", message: "Please name your workout...", preferredStyle: .alert)
let addAction = UIAlertAction(title: "Add Workout", style: .default) { (UIAlertAction) in
//Add workout to database
//Create a two dimensional array object in Realm with numbers corresponding to each day of the week.
//Append workouts to the day in the dictionary that the user selects.
let newWorkout = Workouts()
let dow = WeekDays()
dow.day = self.daysOfWeek[self.picker.selectedRow(inComponent: 0)]
newWorkout.name = textField.text!
dow.workouts.append(newWorkout)
self.save(newDay: dow)
}
alert.addTextField { (alertTextField) in
alertTextField.placeholder = "Muscle Group"
textField = alertTextField
alertTextField.inputView = self.picker
}
alert.addAction(addAction)
present(alert, animated: true, completion: nil)
}
func save(newDay: WeekDays){
do {
try realm.write {
realm.add(newDay)
}
} catch {
print("Error saving workout \(error)")
}
WorkoutsTableView.reloadData()
}
func updateModel(at indexPath: IndexPath){
if let workoutForDeletion = self.days?[indexPath.row]{
do {
try self.realm.write {
self.realm.delete(workoutForDeletion)
}
} catch {
print("Error deleting workout, \(error)")
}
}
WorkoutsTableView.reloadData()
}
func loadCategories(){
days = realm.objects(WeekDays.self)
WorkoutsTableView.reloadData()
}
@IBAction func EditWorkout(_ sender: UIBarButtonItem) {
}
}
extension WorkoutsViewController : UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 7
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return daysOfWeek[row]
}
}
For your first question, I don't think you need to worry.
You should inherit from CollapsibleTableSectionViewController
if that is what you want to use. That itself extends UIViewController
so you don't need to do it yourself.
I can't see any SwipeTableViewController
in the SwipeCellKit - you just need to implement the delegate somewhere (in your main view controller code is fine) and you can 'inherit from' (actually, 'implement') this as it is a protocol, not a class (look into the difference between classes and protocols to find out why).
I can't see the relevant source code for your second question, but maybe that needs a separate question anyway.