UITableViewに、
この画像のように、
横長画像の上に日付が上に被せて配置してあるように作成しているのですが、
最初に表示されているもの(この場合5つ)は不具合がありません。ですが、一番下まで行った際に追加のデータをスクロールして下に見に行けるようになっていて、その際の横長画像の順序がバラバラになってしまいます。日付は正常な順番で出力されます。日付と横長画像はapiにリクエストして取得しており、返ってくるjsonの値は何も問題がありません。ちなみにapiは10セットずつ情報を返してくれて(日付と横長画像で1セット)、リクエストパラメータの"page"の値を増やすことでその次の10セットを取得しています。下にソース全文を添付致しますが、何がおかしいのでしょうか?さっぱりわかりません。
コード中のAlamofire.requestの部分でimageをリサイズしており、
foreachの中でそのような処理をしているので、間に合わなくなり、早く終わったものから
配列に入ってしまっているのかとか考えましたが、よくわかりませんでした。
試したことは、foreachのindexの順番を調べると、[1,3,2,4,5...]と順番がおかしくなる部分があったので、また別の配列を用意してそれにindexを正しい順番でソートしたものを格納し、
最後にそれでwideImageを並び替えるといったことも試しましたが、ダメでした。
何か教えていただけますと幸いでございます。
import UIKit import Firebase import Alamofire import AlamofireImage import SwiftyJSON class TestViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,CreateDatadelegate,UIWebViewDelegate { @IBOutlet var table: UITableView! var wideImage:[UIImage] = [] //横長画像 var date:[String] = [] //日時 var appDelegate:AppDelegate = UIApplication.shared.delegate as! AppDelegate let sw = DeviceSize.screenWidth() let sh = DeviceSize.screenHeight() var scrollcount:Int = 1 var loadingflg = true override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. table.delegate = self table.dataSource = self self.table.backgroundColor = UIColor.clear self.table.estimatedRowHeight = 200.0 self.table.rowHeight = UITableViewAutomaticDimension //self.table.reloadData() } func complete(_ param: [String : String]) { let ud = UserDefaults.standard let id = ud.string(forKey: "id") let pass = ud.string(forKey: "pass") let param = ["id":id!,"passwd":pass!,"page":"1"] self.scrollcount = 1 self.loadingflg = true //wideImage Alamofire.request("http://testapi~.php",method: .post, parameters: param).responseJSON { response in guard let object = response.result.value else{ return } let jsons = JSON(object) self.date = [] self.wideImage = [UIImage](repeating: UIImage(), count: jsons["list"].count) jsons["list"].forEach { (index, img_path) in self.date.append(img_path["date"].string!) Alamofire.request(img_path["url"].string!).responseImage { response in debugPrint(response.result) if let image = response.result.value { let imgratio:CGFloat = (image.size.height)/(image.size.width) let iw = CGFloat(self.sw) let resize = image.ResizeÜIImage(width: iw, height: iw*imgratio) self.wideImage.remove(at: Int(index)!) self.wideImage.insert(resize!, at: Int(index)!) } if self.wideImage.count == jsons["list"].count { print("wideImagecount(self.wideImage.count)") self.table.reloadData() } } } }//wideImage } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func viewDidLayoutSubviews() { print(self.sw) } /// セルの個数を指定するデリゲートメソッド(必須) func tableView(_ table: UITableView, numberOfRowsInSection section: Int) -> Int { return self.wideImage.count } // Section数 func numberOfSections(in table: UITableView) -> Int { return 1// 表示したいSection数 } // Sectionの上部のスペース func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 0 } // Sectionの下部のスペース func tableView(_ tableView: UITableView,heightForFooterInSection section: Int) -> CGFloat { return 0 } /// セルに値を設定するデータソースメソッド(必須) func tableView(_ table: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // セルを取得する guard let cell = table.dequeueReusableCell(withIdentifier: "thirdpagecell", for: indexPath) as? Thirdpagecell else { fatalError("Your cellIdentifier is invalid") } guard self.wideImage.count != 0 else { return cell } print(wideImage.count) print("indexPath.rowの値は:(indexPath.row)") cell.layoutWithData(wideImage[indexPath.row],Text1: date[indexPath.row]) cell.backgroundColor = UIColor.clear ///選択時のセルの色 let cellSelectedBgView = UIView() cellSelectedBgView.backgroundColor = UIColor.clear cell.selectedBackgroundView = cellSelectedBgView return cell } /// セルが選択された時に呼ばれるデリゲートメソッド func tableView(_ table: UITableView, didSelectRowAt indexPath: IndexPath) { } /* *section header の設定 */ func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let label = UIView() label.backgroundColor = UIColor.clear return label } /* *section footer の設定 */ func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { let label = UIView() label.backgroundColor = UIColor.clear return label } func scrollViewDidScroll(_ scrollView: UIScrollView) { if self.table.contentOffset.y + self.table.bounds.size.height > self.table.contentSize.height && self.table.isDragging { guard self.loadingflg else { return } load_data() } } func load_data(){ self.loadingflg = false self.scrollcount = self.scrollcount + 1 print("一番下に来た時の処理") let ud = UserDefaults.standard let id = ud.string(forKey: "id") let pass = ud.string(forKey: "pass") let param = ["id":id!,"passwd":pass!,"page":String(self.scrollcount)] //wideImage Alamofire.request("http://testapi~.php",method: .post, parameters: param).responseJSON { response in guard let object = response.result.value else{ return } let jsons = JSON(object) jsons["list"].forEach { (_, img_path) in self.date.append(img_path["date"].string!) Alamofire.request(img_path["url"].string!).responseImage { response in debugPrint(response.result) if let image = response.result.value { let imgratio:CGFloat = (image.size.height)/(image.size.width) let iw = CGFloat(self.sw) let resize = image.ResizeÜIImage(width: iw, height: iw*imgratio) self.wideImage.append(resize!) } } } if self.wideImage.count > 16*(self.scrollcount/4){ self.loadingflg = true self.table.reloadData() } }//wideImage } } class Thirdpagecell: UITableViewCell { @IBOutlet weak var wideImage: UIImageView! @IBOutlet weak var date: UILabel! func layoutWithData(_ img:UIImage,Text1 text1:String) { wideImage.image = img wideImage.contentMode = UIViewContentMode.scaleAspectFit date.text = text1 } }
また配列のことで気づいたことがあるので、追記致します。
load_date()のforeach部分ですが
indexを取得しようとしたところ、alamofireImageのメソッドに入るまでは
綺麗な順番で数字が出力されるのに対し、メソッド内ではindexの順番がバラバラに
なります。また、新たに"BannerImage"というString型の配列を用意して、
"banner"と同じ工程をさせて、画像url表示の配列の中身を確認すると、バラバラなindex
通りに画像が並んでおり、tableviewに表示されているものと同じものでした。
このことから、最終的には"banner"の配列の中身を,綺麗に並び変えることができれば良いのではないかと考えたのですが、そもそもなぜalamofireImageの中のindex番号はバラバラになるのでしょうか。。
Alamofire.request("http://testapi~.php",method: .post, parameters: param).responseJSON { response in guard let object = response.result.value else{ return } let jsons = JSON(object) jsons["list"].forEach { (index, img_path) in self.race_date_time.append(img_path["date"].string!) print("ここでのindexの値は:(index)")//結果:0,1,2,3,.....綺麗な順番 Alamofire.request(img_path["url"].string!).responseImage { response in debugPrint(response.result) if let image = response.result.value { print("image downloaded: (image)") print("ここでのindexの値は:(index)")//結果:3,0,1,2,.....バラバラな順番 let imgratio:CGFloat = (image.size.height)/(image.size.width) let iw = CGFloat(self.sw) let resize = image.ResizeÜIImage(width: iw, height: iw*imgratio) self.BannerImage.append(img_path["img_path"].string!) print("BannerImageは(self.BannerImage)") self.banner.append(resize!) } } }