UITableViewで、下と上にテーブルを引っ張って更新するときのエラー
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 2,087
UITableViewを使って、データのリフレッシュ・ページングをしたいと考えているのですが、
下に引っ張ってリフレッシュするときに
大きく下に引っぱってしまうと、エラーが起きていまいます。
fatal error: Array index out of range
はじめは、リフレッシュを行った時に同時にページング処理も行っているためだと思うのですが、現状エラーを解決することができません。
import Foundation
import UIKit
import Alamofire
import SwiftyJSON
class RequestViewController:UIViewController,UITableViewDataSource,UITableViewDelegate{
@IBOutlet weak var table: UITableView!
private var userNameArray: [String]! = []
private var userImgArray: [String]! = []
private var userIDArray: [Int]! = []
private var userIndexArray: [Int]! = []
private var userImage: String!
private var dataCount:Int! = 0
private var loadingCounter:Int! = 0
private var beforeUserIDArray:Int! = 0
private let loadNow: UIActivityIndicatorView! = UIActivityIndicatorView(frame: CGRectMake(0, 0, 50, 50))
var refreshControl:UIRefreshControl! = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
self.table.backgroundColor = UIColor(white: 0.95, alpha: 1)
self.getRequest()
self.refreshControl = UIRefreshControl()
//self.refreshControl.attributedTitle = NSAttributedString(string: "引っ張って更新")
self.refreshControl.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged)
self.table.addSubview(refreshControl)
//// スクロールする毎にロードする際のインジケーター表示
self.loadNow.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
}
func refresh()
{
print("refresh!!!")
//取得した配列を開放
self.userNameArray.removeAll()
self.userImgArray.removeAll()
self.userIDArray.removeAll()
self.userIndexArray.removeAll()
//loading countの初期化
self.loadingCounter = 0
//セルのカウントを初期化
self.dataCount = 0
self.getRequest()
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
print("SCROLL")
if self.table.contentOffset.y >= self.table.contentSize.height - self.table.bounds.size.height {
print("self.table.contentOffset.y = \(self.table.contentOffset.y)")
print("self.table.contentSize.height =\(self.table.contentSize.height)")
print("self.table.bounds.size.height = \(self.table.bounds.size.height)")
if self.loadNow.isAnimating() == false {
print("self.loadNow.isAnimating() == false ")
print(self.loadingCounter)
if self.loadingCounter != 0{
print("scrollViewDidEndDecelerating ")
self.getRequest()
}
}
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// tableCell の ID で UITableViewCell のインスタンスを生成
let cell = self.table.dequeueReusableCellWithIdentifier("requestTableCell", forIndexPath: indexPath)
//選択しても色がつかない状態にする
cell.selectionStyle = UITableViewCellSelectionStyle.None
// Tag番号1で UILabel インスタンスの生成
let content1 = self.table.viewWithTag(-1) as! UILabel
let content2 = self.table.viewWithTag(-5) as! UILabel
if cell.viewWithTag(-3) != nil && cell.viewWithTag(-4) != nil{
var allowButton: UIButton = UIButton()
allowButton = cell.viewWithTag(-3) as! UIButton
allowButton.addTarget(self, action: "touchAllowBtn:",forControlEvents: .TouchUpInside)
var dontAllowButton: UIButton = UIButton()
dontAllowButton = cell.viewWithTag(-4) as! UIButton
dontAllowButton.addTarget(self, action: "touchDontAllowBtn:", forControlEvents: .TouchUpInside)
content1.text = nil
content1.text = "\(self.userNameArray[indexPath.row])"
content2.text = nil
content2.text = "\(self.userIDArray[indexPath.row])"
self.userImage = self.userImgArray[indexPath.row]
self.setUserImg(cell, path: indexPath.row)
}
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.dataCount != 0 {
return self.dataCount
}
return 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//通知内容読み込み用関数
func getRequest(){
print("loading count = \(self.loadingCounter)")
print("self.refreshControl.refreshing = \(self.refreshControl.refreshing)")
// ローディングアイコン処理
self.table.tableFooterView = self.loadNow
if self.refreshControl.refreshing == false{
self.loadNow.hidden = false
self.loadNow.startAnimating()
}
Alamofire.request(.GET, Const().URL_API + "/activities/showRequest", parameters: ["my_id": 1 , "loading" :self.loadingCounter])
.response { request, response, data, error in
if error == nil {
let json = JSON(data: data!)
//print("JSON = \(json)")
self.dataCount = json["request_data"].count + self.dataCount
for var i = 0; i < json["request_data"].count; i++ {
if(json["request_data"][i]["user_name"] != nil){
self.userNameArray.append(json["request_data"][i]["user_name"].string!)
}else{
self.userNameArray.append("")
}
//ユーザーIDを取得するコードを挿入
if(json["request_data"][i]["user_id"] != nil){
self.userIDArray.append(json["request_data"][i]["user_id"].int!)
}else{
self.userIDArray.append(0)
}
if(json["request_data"][i]["user_img_url"] != nil){
self.userImgArray.append(json["request_data"][i]["user_img_url"].string!)
}else{
self.userImgArray.append("no_data")
}
if(json["request_data"][i]["relation_index"] != nil){
self.userIndexArray.append(json["request_data"][i]["relation_index"].int!)
}else{
self.userIndexArray.append(999)
}
}
self.table.reloadData()
//更新が終わったのでグリグリを削除
if self.loadNow.isAnimating() == true{
self.loadNow.stopAnimating()
}
if self.refreshControl.refreshing == true{
self.refreshControl.endRefreshing()
}
self.loadingCounter = self.loadingCounter + 1
}
else {
print("error!")
}
}
}
//画像処理
func setUserImg(cell: UITableViewCell, path: Int){
let userImage: UIImageView = cell.viewWithTag(-2) as! UIImageView
userImage.backgroundColor = UIColor.lightGrayColor()
userImage.layer.cornerRadius = 27.5
userImage.image = nil
if self.userImage != "no_data" {
Alamofire.request(.GET, self.userImage)
.response { request, response, data, error in
if error == nil {
dispatch_async(dispatch_get_main_queue()) { () in
userImage.image = UIImage(data: data!)
//colonyImage.addGestureRecognizer(colonyImageTapRecognizer)
}
}
else {
print("error!")
}
}
userImage.layer.masksToBounds = true
}
else {
userImage.image = nil
}
}
func touchAllowBtn(sender: UIButton) {
let btn: UIButton! = sender
let cell: UITableViewCell = btn.superview?.superview as! UITableViewCell
let index:Int = (self.table.indexPathForCell(cell)?.row)!
if sender.currentTitle == "allow"{
print("userIndex = \(self.userIndexArray[index])")
print("userID = \(self.userIDArray[index])")
}
}
func touchDontAllowBtn(sender: UIButton) {
let btn: UIButton! = sender
let cell: UITableViewCell = btn.superview?.superview as! UITableViewCell
let index:Int! = (self.table.indexPathForCell(cell)?.row)!
print("ID = \(index)")
if sender.currentTitle == "dont"{
print("userID = \(self.userIDArray[index])")
self.deleteCell(self.userIDArray[index])
}
}
}
なにかありましたら、随時補足させていただきますのでよろしくお願い致します。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
上記エラーは、配列に対して存在しないindexへのアクセスがあったときに起きるエラーのようですね。
TableViewのセル数はdataCountの値を使用していますが、
userNameArray,userImgArray,userIDArray,userIndexArray
それぞれの配列数と同期がとれていないのではないのでしょうか?
それぞれのパラメータごとに配列を用意するのではなく、
class ResponseData: NSObject {
let userImgArray: String
let userID: Int
let userIndex: Int
}
な感じでモデルクラスを作成して、このモデルを配列で管理すれば、こういった問題は発生しないのかなと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる