TableView.reloadData() is not working ? (SWIFT)

2020-04-21 01:49发布

问题:

I am developing a Quiz App which fetches questions from a JSON. I have already used reloadData for TableView many times & worked as expected. But now I am fetching Questions using Alamofire & saving it in a Array & fetching the Questions from the Array.

But it returns Array is Out of Index.

How can i Display the First item of the Array in the first Cell ?

VC

class ExamController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var Exam: UITableView!

    var CourseID : String!
    var EID : String!
    var EName : String!
    var ET : String!

    var QArray : [String] = []

    var progress = GradientCircularProgress()


    override func viewDidLoad() {
        super.viewDidLoad()
        progress.show(style:MyStyle())
        // JUST TRIED
        dispatch_async(dispatch_get_main_queue(), {
            self.getQuestions()
            // DO SOMETHING ON THE MAINTHREAD
            self.Exam.reloadData()
        })

        self.Exam.tableFooterView = UIView(frame: CGRectZero)
        self.Exam.tableFooterView?.hidden = true
    }

    func getQuestions(){

        if ET == "CHAPTER" {
            Alamofire.request(.GET, "http://www.wis.com/index.php/capp/chapter_questions_details/\(CourseID)/\(EID)/10")
                .responseJSON { (_, _, data, _) in
                    println(data)
                    let json = JSON(data!)
                    let catCount = json.count
                    for index in 0...catCount-1 {
                        let q = json[index]["QUESTION"].string
                        self.QArray.append(q!)
                        println(self.QArray)
                    }

            }

            self.progress.dismiss()
            self.Exam.reloadData()

        } else if ET == "FA" {
            Alamofire.request(.GET, "http://www.wis.com/index.php/capp/fa_questions_by_course_id/\(CourseID)/\(EID)")
                .responseJSON { (_, _, data, _) in
                    println(data)
                    let json = JSON(data!)
                    let catCount = json.count
                    for index in 0...catCount-1 {
                        let q = json[index]["QUESTION"].string
                        self.QArray.append(q!)
                        println(self.QArray)
                    }

            }
                        self.progress.dismiss()
                        self.Exam.reloadData()
    }
}

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

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


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.row == 0{
            let cell = self.Exam.dequeueReusableCellWithIdentifier("Question") as! QuestionCell

            cell.Questionlabel?.text = QArray[0]
            return cell

        }
        else
        {
            let cell = self.Exam.dequeueReusableCellWithIdentifier("Option") as! OptionCell

            cell.Optionlabel?.text = "Option"
            return cell

        }
    }

回答1:

You need to reload your tableview inside Alamofire block

And so it will look like

  Alamofire.request(.GET, "http://www.wis.com/index.php/capp/chapter_questions_details/\(CourseID)/\(EID)/10")
            .responseJSON { (_, _, data, _) in
                println(data)
                let json = JSON(data!)
                let catCount = json.count
                for index in 0...catCount-1 {
                    let q = json[index]["QUESTION"].string
                    self.QArray.append(q!)
                    println(self.QArray)
                }
        self.progress.dismiss()
        self.Exam.reloadData()
  }

and yes ofcourse, as per given answers and comments,

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.QArray?.count ?? 0 // will return 0 rows if QArray is empty
}

This may help!



回答2:

Use dispatch queue to call your completion handler in .responseJSON , and from there update your UI .

E.G.

Alamofire.request(.GET, postEndpoint, headers: headers)
        .responseJSON { response in 

    // Do something...

    dispatch_async(dispatch_get_main_queue(), {
        // Update your UI here
        self.tableView.reloadData()
     })
}


回答3:

Sounds like you need to put the reload into the completion handler so that you have data when you try to update the UI.

To be safe (in case of other calls to reload), you can also guard your return value in numberOfRowsInSection by checking whether there are at least 5 items in QArray.