我正在将JSON
的一些数据显示在我的AccordionView
中。问题是我的View线程在我的网络线程之前完成执行。因此,我无法将从数组中获取的数据填充到我的AccordionView中。
因此它显示Array index out of range
例外。我也尝试过使用reloadData方法但它没用。
我研究了这个问题,发现了GCD。我无法弄清楚如何在这个问题上使用GCD。
这是AccordionView图书馆。
import UIKit
import Alamofire
import SwiftyJSON
var CourseIdinController : String!
var CourseDescriptionC: String!
var ChapNameC : [String] = []
var titleLabel : UILabel?
class CoursePageController: UIViewController {
@IBOutlet weak var courseDesc: UITextView!
var CourseName : String!
var ChapName : [String] = []
var LessonName : [String] = []
var myAccordionView : MKAccordionView?
override func viewDidLoad() {
super.viewDidLoad()
self.title = CourseName
self.courseDesc.text = CourseDescriptionC
self.courseDesc.setContentOffset(CGPointZero, animated: true)
view.bounds.size.height = 450.0
myAccordionView = MKAccordionView(frame: CGRectMake(0, 111, CGRectGetWidth(view.bounds), CGRectGetHeight(view.bounds)));
println(ChapNameC.count)
myAccordionView!.delegate = self;
myAccordionView!.dataSource = self;
view.addSubview(myAccordionView!);
getData()
getlData()
}
func getData(){
Alamofire.request(.GET, "http://www.wgve.com/index.php/capp/get_chapter_by_course_id/\(CourseIdinController)")
.responseJSON { (_, _, data, _) in
let json = JSON(data!)
let catCount = json.count
for index in 0...catCount-1 {
let cname = json[index]["CHAPTER_NAME"].string
self.ChapName.append(cname!)
println(self.ChapName[index])
}
self.myAccordionView!.tableView?.reloadData()
}}
func getlData(){
Alamofire.request(.GET, "http://www.wgve.com/index.php/capp/get_lesson_by_course_id/\(CourseIdinController)")
.responseJSON { (_, _, data, _) in
let json = JSON(data!)
let catCount = json.count
for index in 0...catCount-1 {
let cname = json[index]["LESSON_NAME"].string
self.LessonName.append(cname!)
}
self.myAccordionView!.tableView?.reloadData()
}}
func accordionView(accordionView: MKAccordionView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell? = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: nil)
//cell?.imageView = UIImageView(image: UIImage(named: "lightGrayBarWithBluestripe"))
// Background view
var bgView : UIView? = UIView(frame: CGRectMake(0, 0, CGRectGetWidth(accordionView.bounds), 50))
var bgImageView : UIImageView! = UIImageView(image: UIImage(named: "lightGrayBarWithBluestripe"))
bgImageView.frame = (bgView?.bounds)!
bgImageView.contentMode = UIViewContentMode.ScaleToFill
bgView?.addSubview(bgImageView)
cell?.backgroundView = bgView
// You can assign cell.selectedBackgroundView also for selected mode
cell?.textLabel?.text = LessonName[0]
return cell!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// MARK: - Implemention of MKAccordionViewDatasource method
extension CoursePageController : MKAccordionViewDatasource {
func numberOfSectionsInAccordionView(accordionView: MKAccordionView) -> Int {
println(ChapName.count)
return ChapName.count
}
func accordionView(accordionView: MKAccordionView, numberOfRowsInSection section: Int) -> Int {
println(LessonName.count)
return LessonName.count
}
}
// MARK: - Implemention of MKAccordionViewDatasource method
extension CoursePageController : MKAccordionViewDatasource {
func numberOfSectionsInAccordionView(accordionView: MKAccordionView) -> Int {
return ChapName.count
}
func accordionView(accordionView: MKAccordionView, numberOfRowsInSection section: Int) -> Int {
return LessonName.count
}
}
// MARK: - Implemention of MKAccordionViewDelegate method
extension CoursePageController : MKAccordionViewDelegate {
func accordionView(accordionView: MKAccordionView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50
}
func accordionView(accordionView: MKAccordionView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func accordionView(accordionView: MKAccordionView, viewForHeaderInSection section: Int, isSectionOpen sectionOpen: Bool) -> UIView? {
var view : UIView! = UIView(frame: CGRectMake(0, 0, CGRectGetWidth(accordionView.bounds), 50))
// Background Image
var bgImageView : UIImageView = UIImageView(frame: view.bounds)
bgImageView.image = UIImage(named: ( sectionOpen ? "grayBarSelected" : "grayBar"))!
view.addSubview(bgImageView)
// Arrow Image
var arrowImageView : UIImageView = UIImageView(frame: CGRectMake(15, 15, 20, 20))
arrowImageView.image = UIImage(named: ( sectionOpen ? "close" : "open"))!
view.addSubview(arrowImageView)
// Title Label
titleLabel = UILabel(frame: CGRectMake(50, 0, CGRectGetWidth(view.bounds) - 120, CGRectGetHeight(view.bounds)))
if (ChapName.count != 0) {
let count = ChapName.count
for index in 0...count-1 {
titleLabel!.text = self.ChapName[index]
}
}
titleLabel!.textColor = UIColor.whiteColor()
view.addSubview(titleLabel!)
return view
}
}
注意:
它显示我的错误,因为ChapName&课程名称数组为空。如果我硬编码值。它在我的控制台中打印两个数组。
可能是accordionView不支持重载方法吗? 或者我哪里错了?
更新
fatal error: Can't form Range with end < start
的错误
请参阅此link 2. titleLabel仅返回数组中的最后一项。我不知道为什么?
答案 0 :(得分:0)
关于上述代码无效的原因:
无论JSON响应如何,numberOfRowsInSection
都会返回硬编码值。
关于停止UI线程:
我们有点高兴你不能这样做。 GCD
可以帮助您有效地共享处理器时间,这与保持UI线程人质完全相反。如果您的网络线程以某种方式挂起,请想象后果。 UI线程会发生什么?不要这样做。
解决方案:您的UI线程足够聪明,可以处理数据缺失。即不返回部分或单元格的硬编码计数。当您收到数据时,更新您的记录(模型),向UI发送刷新消息(例如reloadData
中的UITableView
)。
答案 1 :(得分:0)
你应该确保你所有的json数据都成功地存储在一个数组中#accord; accordionDataArray&#34;在您尝试重新加载之前。
注意:确保数据源方法 numberOfRowsInSection 和 numberOfSectionsInAccordionView 依赖于accordionDataArray内容(或您拥有的任何数组)来确定数据源的部分和行的数量。手风琴。
P.S。无论如何为什么要在循环中重新加载手风琴的内容? 这样做:
for index in 0...catCount-1 {
let cname = json[index]["CHAPTER_NAME"].string
self.ChapName.append(cname!)
println(self.ChapName[index])
}
self.myAccordionView!.tableView?.reloadData()
<强>更新强> 为了通过ChapName&amp;当lessonName数组为空时,会要求它们显示某些值,您需要在它们出现时检查它是否正确:
if (ChapName.count != 0) {
titleLabel!.text = self.ChapName[0]
}
if (LessonName.count != 0){
// do something
}
确保更新代码并进行测试。在方法中:
func accordionView(accordionView: MKAccordionView, viewForHeaderInSection section: Int, isSectionOpen sectionOpen: Bool) -> UIView? {
[...]
if (ChapName.count != 0) {
titleLabel!.text = self.ChapName[0]
}
[...]
}
更新2 :您正在使用的图书馆似乎不允许部分的数量为0.我建议您联系图书馆的所有者,如果可以的话#39 ; t确保节的数量至少为1。
关于你的另一个问题,titleLabel始终是数组的最后一项,你需要更改它:
if (ChapName.count != 0) {
let count = ChapName.count
for index in 0...count-1 {
titleLabel!.text = self.ChapName[index]
}
}
进入这个:
titleLabel!.text = self.ChapName[section]