Swift5.2 TableView CSVを用いたSectionの設定方法
解決済
回答 1
投稿
- 評価
- クリップ 1
- VIEW 257
前提・実現したいこと
ここに質問の内容を詳しく書いてください。
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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
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%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
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 番号を入れるとかしないと区別できないのでは。(これはあくまでも一つの例で、やり方は他にもいろいろ考えられますが。)