Search code examples
swift3tableviewalamofireuislider

Getting Values from UISliders alongside UserID (linking User to section number?)


I'm working on creating a 'Rate' feature in my app where it pulls the users to rate from an external API. I then create a TableView which adds cells that contain a section name (the name of the User) and a UISlider.

What I'm trying to do is gather the data from the UISliders along with the User ID associated with the User who's section it is so that I can call a POST action to the API to send the rating data too.

enter image description here

Here's the code I have: (For the record, first time with Swift, the comments are me trying to figure out how to do this). Any ideas?

import UIKit
import Alamofire


class RateViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var submitButton: UIButton!
    @IBOutlet weak var activeSurveyLabel: UILabel!


    private var myTableView: UITableView!
    var usersToRate = [User]()
    var activeSurveyId: String?
    var rateData = [String: Int]()
    var sectionIdToUserId = [Int: String]()
    var userIdSection = [Int: String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        submitButton.isHidden = true

        submitButton.addTarget(self, action: #selector(pressSubmitButton(button:)), for: UIControlEvents.touchUpInside)

        activeSurveyLabel.isHidden = false


        self.loadUsersToRate()


        Alamofire.request(RateRouter.getSurvey()).responseJSON { response in
            debugPrint(response)


            if let string = response.result.value as? [[String: Any]]{

                if string.count == 0 {
                    return
                }

                self.submitButton.isHidden = false
                self.activeSurveyLabel.isHidden = true

                for survey in string {
                    if let survey = Survey(json: survey) {
                        self.activeSurveyId = survey._id!
                        print(survey._id!)
                    }
                }


                //if there's a result, show slider bars for each person on the team with rating scales (except for the person logged in)
                //have a submit button with a post request for the votes

                let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
                let displayWidth: CGFloat = self.view.frame.width
                let displayHeight: CGFloat = barHeight * CGFloat(self.usersToRate.count * 5)

                self.myTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
                self.myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
                self.myTableView.dataSource = self
                self.myTableView.delegate = self
                self.view.addSubview(self.myTableView)


            } else {
                print(response.result.error!)
                let label = UILabel()
                label.center = self.view.center
                label.text = "No Active Surveys"
                self.view.addSubview(label)
            }

        }




        // Do any additional setup after loading the view.
    }

    func loadUsersToRate() {
        Alamofire.request(RateRouter.getUsers()).responseJSON { response in
            guard let jsonArray = response.result.value as? [[String: Any]] else {
                print("didn't get array, yo")
                return
            }

            for item in jsonArray {
                if let user = User(json: item) {
                    self.usersToRate.append(user)

                    self.rateData.updateValue(5, forKey: user.userId!) //initialize user average data at 5 in case they don't change it
                    print (self.rateData)
                }
            }
        }
    }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Num: \(indexPath.row)")
        print("Value: \(usersToRate[indexPath.row])")

    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }


    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        self.sectionIdToUserId.updateValue(usersToRate[section].userId!, forKey: section)
        print(self.sectionIdToUserId)
        return "\(usersToRate[section].name!)"
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return usersToRate.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)

        let slider = UISlider(frame: CGRect(x: 0, y:0, width: 400, height: 44))
        slider.isUserInteractionEnabled = true
        slider.minimumValue = 1
        slider.maximumValue = 10
        slider.value = 5
        slider.tag = indexPath.section
        slider.addTarget(self, action: #selector(sliderValueChange(sender:)), for: UIControlEvents.valueChanged)
        cell.addSubview(slider)


        return cell
    }

    func sliderValueChange(sender: UISlider) {
        //get slider value
        var currentValue = Int(sender.value)
        print(currentValue)

        //self.rateData.updateValue(currentValue, forKey: self.sectionIdToUserId.values[sender.])



        //get user id for that value
        //self.rateData.updateValue(currentValue, rateData[section])



       // self.rateData.updateValue(currentValue, forKey: 0)
    }

    func pressSubmitButton(button: UIButton) {


        for user in usersToRate {
          //   Alamofire.request(RateRouter.vote(voteFor: user.userId!, survey: activeSurveyId, rating:))
        }



    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

Solution

  • To answer my own question, what I did was create a different model called 'Votes' that stored the information for each vote.

    Then to fill that array I created a tag for the slider in the tableView based on the section ID and used that to update the current value.

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
    
        let slider = UISlider(frame: CGRect(x: 0, y:0, width: cell.frame.width , height: 44))
    
        slider.tag = indexPath.section
        slider.addTarget(self, action: #selector(sliderValueChange(sender:)), for: UIControlEvents.valueChanged)
        cell.addSubview(slider)
    
    
        return cell
    }
    
    func sliderValueChange(sender: UISlider) {
        //get slider value
        var currentValue = Int(sender.value)
        print(currentValue)
    
        voteData[sender.tag].rating = currentValue
    }