質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.35%

Swift5.2 TableView CSVを用いたSectionの設定方法

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 257

dinoymzk

score 1

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
Swiftを今月から始めた初学者です。
tableviewのsectionの機能について詳しい方いましたらご指導願います。

現在、Swift5 csvを利用したtablviewのページを作っており、indexPath.rowをキーとして、csvの問題を読み込んでいます。
indexPath.rowの値はsectionが変わるごとに1になってしまい,セクションごとにきれいに並べることができません。

該当のソースコード

//
//  IndexViewController.swift

import UIKit


class IndexViewController:  UIViewController,UITableViewDelegate,UITableViewDataSource{

    //スクリーンの横幅、縦幅を定義

    let screenWidth = Int(UIScreen.main.bounds.size.width)
    let screenHeight = Int(UIScreen.main.bounds.size.height)

    //テーブルビューインスタンス作成
    var sampleTableView: UITableView  =   UITableView.init(frame: CGRect.zero, style: .grouped)


    //配列用
    var csvArray: [String] = []
    var quizArray: [String] = []
    var quizCount = 0


    // Sectionで使用する配列を定義する.
    private let sections: Array = ["セクション0", "セクション1", "セクション2"]


//ここから
    override func viewDidLoad() {
        super.viewDidLoad()
        //テーブルビューの設置場所を指定
        sampleTableView.frame = CGRect(x:screenWidth * 0/100, y:screenHeight * 10/100,
                                 width:screenWidth * 100/100, height:screenHeight * 80/100)



        // sampleTableView の dataSource 問い合わせ先を self に
        sampleTableView.delegate = self
        // sampleTableView の delegate 問い合わせ先を self に
        sampleTableView.dataSource = self

        //cellに名前を付ける
        sampleTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")

        //実際にviewにsampleTableViewを表示させる
        self.view.addSubview(sampleTableView)

        //cellの高さを指定
        self.sampleTableView.rowHeight = 50
        //sectionの高さを指定
        self.sampleTableView.sectionHeaderHeight = 20

        //セパレーターの色を指定
        let bgColor = UIColor.darkGray.withAlphaComponent(0.1) // ←好きな色を生成
               self.sampleTableView.backgroundColor = bgColor
               self.sampleTableView.backgroundView?.backgroundColor = bgColor
        sampleTableView.separatorColor = UIColor.blue
        csvArray = loadCSV(fileName: "quiz")
        print(csvArray)

    }



    //セクション数を指定
    func numberOfSections(in sampleTableView: UITableView) -> Int {
        return sections.count
    }

    // セクションのタイトルを返す
    func tableView(_ sampleTableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sections[section]
    }




    //表示するcellの数を指定
    func tableView(_ sampleTableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         if section == 0 {
            return 0
         } else if section == 1 {
        return 4
         } else {
        return 2
        }
    }





    //cellのコンテンツ
    func tableView(_ sampleTableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: "cell")
        //cellにはsampleArrayが一つずつ入るようにするよ!
        quizArray = csvArray[indexPath.row].components(separatedBy: ",")
        cell.textLabel?.text = quizArray[1]
        cell.detailTextLabel?.text =  "前回: \(quizArray[2])"
        cell.detailTextLabel?.textColor = UIColor.blue
        print(indexPath.section) //分けない限り0固定
        return cell
    }


    //cellが選択された時の処理
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("\(indexPath.row)番セルが押されたよ!")


     let vc = QuizViewController()
        vc.englishQuizzes = fetchQuizzes()
        vc.index = indexPath.row
        let nav = UINavigationController(rootViewController: vc)
        //フルスクリーンで実施
        nav.modalPresentationStyle = .fullScreen
        present(nav, animated: true, completion: nil)

    }


    private func fetchQuizzes() -> [Quiz] {
        let quizs: [Quiz] = loadCSV(fileName: "quiz").map {
            let quiz = $0.components(separatedBy: ",")
            let choice = quiz.suffix(from: 3)
                .enumerated().map { "\n\($0.offset + 1) \($0.element)" }.joined(separator: "\n")
            let question = "\(quiz[1])\n\n\(choice)"
            let Exp = "\(quiz[0])"
            return Quiz(question: question,Exp: Exp, answerCount: 5, answer: Int(quiz[2])!)
        }
        return quizs
    }



func loadCSV(fileName: String) -> [String] {
    let csvBundle = Bundle.main.path(forResource: fileName, ofType: "csv")!
    do {
        let csvData = try String(contentsOfFile: csvBundle,encoding: String.Encoding.utf8)
        let lineChange = csvData.replacingOccurrences(of: "\r", with: "\n")
        csvArray = lineChange.components(separatedBy: "\n").filter { !$0.isEmpty }
    } catch let error as NSError {
print(error.localizedDescription)
    }
    return csvArray
    }


//end
}




**************************************
//
//  Quiz.swift

struct Quiz {
    let question: String
    let Exp: String
    let answerCount: Int
    let answer: Int
}

class QuizFixture {
    static func test(
        question: String = "test",
        Exp: String = "解答がはいるよ",
        answerCount: Int = 4,
        answer: Int = 2
        ) -> Quiz {
        return Quiz(question: question,Exp: Exp, answerCount: answerCount, answer: answer)
    }    
}

**************************************
//
//  quiz.csv

a,1,1,1,1,1
b,2,2,2,2,2
c,3,3,3,3,3
d,4,4,4,4,4
e,5,5,5,5,5
f,6,6,6,6,6
g,7,7,7,7,7
h,8,8,8,8,8
i,9,9,9,9,9

試したこと

tableviewにした際に下のように可変にセクションを区切りたい。
section0
a
a
c
section1
d
e
f
g
section2
h
i

補足情報(ツールのバージョン:Xcode Version 11.4.1 (11E503a))

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hoshi-takanori

    2020/05/20 01:47

    quiz.csv にセクションを区切るための情報が必要なのでは。

    キャンセル

  • dinoymzk

    2020/05/20 11:15

    csvArrayで改行ごと、,quizArrayで列ごとに区切っています。
    次のfuncで改行ごとにCSVのデータを区切っています。
    →func loadCSV(fileName: String) -> [String] {
    let csvBundle = Bundle.main.path(forResource: fileName, ofType: "csv")!
    do {
    let csvData = try String(contentsOfFile: csvBundle,encoding: String.Encoding.utf8)
    let lineChange = csvData.replacingOccurrences(of: "\r", with: "\n")
    csvArray = lineChange.components(separatedBy: "\n").filter { !$0.isEmpty }
    } catch let error as NSError {
    print(error.localizedDescription)
    }
    return csvArray
    }



    また、次のfuncで列ごと","でCSVのデータを区切っています。
    //cellのコンテンツ
    func tableView(_ sampleTableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: "cell")
    //cellにはsampleArrayが一つずつ入るようにするよ!
    → quizArray = csvArray[indexPath.row].components(separatedBy: ",")
    cell.textLabel?.text = quizArray[1]
    cell.detailTextLabel?.text = "前回: \(quizArray[2])"
    cell.detailTextLabel?.textColor = UIColor.blue
    print(indexPath.section) //分けない限り0固定
    return cell
    }

    これにもう一つ変数をsectionArrayなるものを追加して、quizArray[1]を入れていきましたが、うまくいかず・・・・です。

    キャンセル

  • hoshi-takanori

    2020/05/20 13:22

    それは分かりますが、csv の内容が
    a,1,1,1,1,1
    b,2,2,2,2,2
    c,3,3,3,3,3
    d,4,4,4,4,4
    e,5,5,5,5,5
    f,6,6,6,6,6
    g,7,7,7,7,7
    h,8,8,8,8,8
    i,9,9,9,9,9
    として、section 0 は a 〜 c、section 1 は d 〜 g、section 2 は h 〜 i だと判断するための情報が足りないってことです。

    例えば各行の先頭に、
    0,a,1,1,1,1,1
    0,b,2,2,2,2,2
    0,c,3,3,3,3,3
    1,d,4,4,4,4,4
    ...
    のように section 番号を入れるとかしないと区別できないのでは。(これはあくまでも一つの例で、やり方は他にもいろいろ考えられますが。)

    キャンセル

回答 1

check解決した方法

0

func tableView(_ sampleTableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 3
} else if section == 1 {
return 4
} else {
return 2
}
}
としたことで解決出来ました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る