Доступ к переменным внутри внешнего класса swift - PullRequest
0 голосов
/ 22 января 2020

У меня есть Viewcontroller.swift файл. Этот файл содержит 2 класса. Один класс является глобальным классом с именем Exercise, а другой класс является просто обычным классом Viewcontroller. Мой класс Exercise содержит несколько переменных, например, excerciseReps. Я пытаюсь получить доступ к этим переменным в моем классе Viewcontroller, чтобы изменить их значения. Однако мне трудно получить доступ к этим переменным, чтобы я мог их редактировать из-за моего ограниченного понимания swift. Кто-нибудь может пролить свет на это для меня? Например, изменение значения excerciseReps на «привет», когда нажата кнопка «Готово», класс ViewController.

import Foundation
import UIKit

private let reuseidentifier = "Cell"

struct cellData {
var opened = Bool()
var title = String()
var exerciseData = [String]()
var repsSetsWeightsData = [String]()
}


struct Contact {
var id:String = "Contact - \(UUID())"
var fullname: String
var exercises : [Exercise]
}

 class Exercise : NSObject , NSSecureCoding{

   static var supportsSecureCoding: Bool = true

   var excerciseName: String
   var excerciseReps: String
   var excerciseSets: String
   var excerciseWeights: String

    init(Name : String, Reps : String, Sets : String, Weights : String) {
    excerciseName = Name
    excerciseReps = Reps
    excerciseSets = Sets
    excerciseWeights = Weights
    }

    func encode(with aCoder: NSCoder) {
    aCoder.encode(excerciseName, forKey: "excerciseName")
    aCoder.encode(excerciseReps, forKey: "excerciseReps")
    aCoder.encode(excerciseSets, forKey: "excerciseSets")
    aCoder.encode(excerciseWeights, forKey: "excerciseWeights")
    }

    required convenience init?(coder aDecoder: NSCoder) {
    let excerciseName = aDecoder.decodeObject(forKey: "excerciseName") as! String
    let excerciseReps = aDecoder.decodeObject(forKey: "excerciseReps") as! String
    let excerciseSets = aDecoder.decodeObject(forKey: "excerciseSets") as! String
    let excerciseWeights = aDecoder.decodeObject(forKey: "excerciseWeights") as! String

    self.init(Name: excerciseName, Reps: excerciseReps, Sets: excerciseSets, Weights: excerciseWeights)

    }


}


class ContactController: UITableViewController, UIPickerViewDelegate, UIPickerViewDataSource {

//created items
//Done button for uipicker
let TheDoneButton: UIButton = {
    let Done = UIButton()
    Done.setTitle("Done", for: .normal)
    Done.setTitleColor(UIColor(red: 10/255, green: 128/255, blue: 253/255, alpha: 1), for: .normal)
    Done.backgroundColor = .white
    Done.titleLabel?.font = Done.titleLabel?.font.withSize(20)
    Done.addTarget(self, action: #selector(uipickerDoneButtonPressed), for: .touchDown)
    Done.translatesAutoresizingMaskIntoConstraints = false
    return Done
}()


var tableViewData = [cellData]()
var contacts = [Contact]()

override func viewDidLoad() {
    super.viewDidLoad()

    //getting data from CoreData
    self.contacts = CoreDataManager.sharedInstance.retrieveDataFromCoreData()
    tableView.register(UINib(nibName: "ExerciseCell", bundle: nil), forCellReuseIdentifier: "ExerciseCell")

    for contact in contacts{
        //var sectionData = [String]()
        var exerciseData = [String]()
        var repsSetsWeightsData = [String]()
        for exercise in contact.exercises{
            let name = exercise.excerciseName
            let sets = exercise.excerciseSets
            let reps = exercise.excerciseReps
            let weights = exercise.excerciseWeights


            exerciseData.append(name)
            repsSetsWeightsData.append("Rep: " + reps + "   Set: " + sets + "   kg: " + weights)

        }

        self.tableViewData.append(cellData.init(opened: false, title: contact.fullname, exerciseData:exerciseData, repsSetsWeightsData: repsSetsWeightsData))
    }


    self.tableView.reloadData()
    self.navigationController?.navigationBar.prefersLargeTitles = true
    self.navigationItem.title = "Workouts"

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(handleCancel))

    view.backgroundColor = .white
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: reuseidentifier)

}


@IBAction func handleAddContact(_ sender: Any) {
    let controller = AddContactController()
    controller.delegate = self

    self.present(UINavigationController(rootViewController: controller), animated: true, completion: nil)

}


@IBAction func handleCancel(_ sender: Any){
    self.dismiss(animated: true, completion: nil)
}


//UITABLEVIEW
override func numberOfSections(in tableView: UITableView) -> Int {
    //new
    return tableViewData.count
}

override func tableView(_ tableView: UITableView,
                        numberOfRowsInSection section: Int) -> Int {
     //new
    if tableViewData[section].opened == true {
        return tableViewData[section].exerciseData.count + 1
    }else {
        return 1
    }
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: reuseidentifier, for: indexPath)
        cell.textLabel?.text = tableViewData[indexPath.section].title
        return cell
    }else {
        //use a different cell identifier if needed
        let cell = tableView.dequeueReusableCell(withIdentifier: "ExerciseCell", for: indexPath) as! ExerciseCell
        cell.exerciseLabel.text = tableViewData[indexPath.section].exerciseData[indexPath.row - 1]
        cell.repsSetsLabel.text = tableViewData[indexPath.section].repsSetsWeightsData[indexPath.row - 1]
        cell.repsSetsLabel.sizeToFit()
        // cell.textLabel?.text = tableViewData[indexPath.section].sectionData[indexPath.row]
        //            cell.textLabel?.text = tableViewData[indexPath.section].sectionData[indexPath.row - 1]
        return cell
        }
    }


    //did select row new
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if tableViewData[indexPath.section].opened == true {
        tableViewData[indexPath.section].opened = false
        let sections = IndexSet.init(integer: indexPath.section)
        tableView.reloadSections(sections, with: .none) //play around with animation
    }else {
        tableViewData[indexPath.section].opened = true
        let sections = IndexSet.init(integer: indexPath.section)
        tableView.reloadSections(sections, with: .none) //play around with animation
    }
    }


    //this is the uipicker string variable this can be put up at the top of the page with all the other variables ...i think
var exercisesInSelectedWorkout = [String]()
var pickedExercise = String()

//being able to delete a row
// this method handles row deletion

    override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    // Edit Button
    let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in

        print(self.contacts[indexPath.section].exercises)
        print(self.tableViewData[indexPath.section].repsSetsWeightsData)

        //setting exercisesInSelectedWorkout to exercise names within workout
        self.exercisesInSelectedWorkout = self.tableViewData[indexPath.section].exerciseData


        //creating uipicker
        var UIPicker: UIPickerView = UIPickerView()
        UIPicker.delegate = self as UIPickerViewDelegate
        UIPicker.dataSource = self as UIPickerViewDataSource

        //Calling UIPicker done buttons:
        self.view.addSubview(self.TheDoneButton)
        self.TheDoneButton.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            self.TheDoneButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            self.TheDoneButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor ,constant: 40),
            ])

        //adding uipicker to screen
        self.view.addSubview(UIPicker)
        UIPicker.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            UIPicker.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            UIPicker.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -150),
            //UIPicker.widthAnchor.constraint(equalToConstant: self.view.frame.width - 64)
            ])

        //locking tableview
        tableView.alwaysBounceVertical = false
    })
    editAction.backgroundColor = UIColor.blue


    // Delete Action UITableView
    let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in

            //removing data from tableview
            self.tableViewData.remove(at: indexPath.section)
            tableView.deleteSections(IndexSet(integer: indexPath.section), with: .top)

            //Deleting Data from CoreData
            CoreDataManager.sharedInstance.deleteDataFromCoreData(contact: self.contacts[indexPath.section])
            print("Items removed from Table View")
            print("Row Deleted")
        })
    deleteAction.backgroundColor = UIColor.red
    return [editAction, deleteAction]
    }


    //UIPICKER Done button function (what happens when done is pressed)
@objc func uipickerDoneButtonPressed(){
    print(exercisesInSelectedWorkout)
    print("hi")
    print(pickedExercise)

}



    //UIPICKER
func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return exercisesInSelectedWorkout.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    let row = exercisesInSelectedWorkout[row]
    return row
    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent  component: Int) {
    let nameOfExercise = self.exercisesInSelectedWorkout[row] as String
    pickedExercise = nameOfExercise
    print(nameOfExercise)
}
}

    //this is an extention to addContactController. this is what happens when the done button is clicked in addcontactcontroller
extension ContactController: AddContactDelegate {
func addContact(contact: Contact) {

    self.dismiss(animated: true) {

        //Saving Data to CoreData
        CoreDataManager.sharedInstance.addContactsToCoreData(contact: contact)
        self.contacts.append(contact)

        //Settings values in table view
        var exerciseData = [String]()
        var repsSetsWeightsData = [String]()

        for exercise in contact.exercises{
            let name = exercise.excerciseName
            let sets = exercise.excerciseSets
            let reps = exercise.excerciseReps
            let weights = exercise.excerciseWeights

            exerciseData.append(name)
            repsSetsWeightsData.append("Rep: " + reps + "  Set: " + sets + "  Kg: " + weights)

        }
        //adding everything into tableview
        self.tableViewData.append(cellData.init(opened: false, title: contact.fullname, exerciseData:exerciseData, repsSetsWeightsData: repsSetsWeightsData))

        self.tableView.reloadData()
    }
   }
}

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Вы можете сделать несколько вещей (я не профессионал, просто пытаюсь помочь)

  1. сделать класс publi c (добавив ключевое слово "Publi c" перед объявлением )
  2. использовать struct и mutate (использовать «мутирование» перед объявлением функции) при изменении переменной (это «разрушит» структуру и создаст ее заново с изменением значения, выполненным функцией)
0 голосов
/ 22 января 2020

Вы можете получить доступ к свойствам и методам вне их класса двумя различными способами.

1: Самый распространенный способ - создать экземпляр класса, в котором они находятся, и затем получить к ним доступ через этот тип,

var ex = Exercise(Name : "name", Reps : "reps", Sets : "sets", Weights : "weight")

//then access them like this 
let name = ex.excerciseName

вам, возможно, придется сделать класс и переменные опубликованными c, и вам все равно нужно будет создать объект, создав его экземпляр, как описано выше.

    Public class Exercise {
       Pubic var excerciseName : String
    }

2: Второй способ - доступ stati c свойства и методы без создания экземпляров, такие как

 let isSecure = Exercise.supportsSecureCoding
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...