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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1942閲覧

swift3 tableViewで新しいsection配列に応じたcellを付与するコード

kifu

総合スコア26

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2016/12/27 11:50

編集2016/12/28 13:24

tableViewの新しいsectionとして日付の配列を作っています(下記コード該当部分1)。このsectionにセルをコードで付与するには、どのように書けば良いのでしょうか。付与するセルは次のとおりです。
var checkListItem: [String : Bool] = [
"アイテム1" : false,
"アイテム2" : false,
"アイテム3" : false,
"アイテム4" : false,
"アイテム5" : false
]
「swift セルをコードで作る」とネットで検索すると、以前のバージョンのコードはありましたがswift3では変換してもエラーが出て動きません。本を見てもストリーボードを使うのが前提になっています。

swift3

1import UIKit 2 3class ViewController : UIViewController, UITableViewDelegate, UITableViewDataSource { 4 5 6 //文字列の日付をDate型に変換するクラス 7 class DateUtils { 8 class func dateFromString(string: String, format: String) -> NSDate { 9 let formatter: DateFormatter = DateFormatter() 10 formatter.dateFormat = format 11 return formatter.date(from: string)! as NSDate 12 } 13 14 class func stringFromDate(date: NSDate, format: String) -> String { 15 let formatter: DateFormatter = DateFormatter() 16 formatter.dateFormat = format 17 return formatter.string(from: date as Date) 18 } 19 } 20 21 22 //テーブルビューのsectionに表示する日付の配列 23 var sectionTitle = ["2016-01-23","2015-12-31","2015-01-12","2016-02-21","2016-12-20"] 24 25 //今日と日付の配列の最後の日差分の日付を配列にするメソッド 26 func getDaysArrayToToday(start:String,max:Int) -> [String] { 27 //テーブルビューのsectionに表示する日付の配列の最後の日 28 let dateArraymax = sectionTitle.max() 29 30 // 日付の配列の最後の日をDate型に変換 31 let dateArraymaxdate = DateUtils.dateFromString(string: dateArraymax!, format: "yyyy/MM/dd") 32 33 //今日と日付の配列の最後の日差 34 let now = NSDate() 35 let dateDifference = Int(now.timeIntervalSince(dateArraymaxdate as Date)/60/60/24) 36 37 var result:[String] = [] 38 let formatter = DateFormatter() 39 formatter.locale = NSLocale(localeIdentifier: "ja_JP") as Locale 40 formatter.dateFormat = "yyyy-MM-dd" 41 // 今日 42 let todayStr = formatter.string(from: Date()) 43 let startDate = formatter.date(from: start)! 44 var components = DateComponents() 45 let calendar = Calendar(identifier: Calendar.Identifier.gregorian) 46 47 for i in 0 ..< max { 48 components.setValue(i,for: Calendar.Component.day) 49 let wk = calendar.date(byAdding: components, to: startDate)! 50 let wkStr = formatter.string(from: wk) 51 print(max) 52 if wkStr > todayStr { 53 break 54 } else { 55 56 result.append(wkStr) 57 } 58 let sectionTitle2 = getDaysArrayToToday(start: dateArraymax!,max: dateDifference) 59 60 //今日と日付の配列の最後の日差分の日付配列を元の日付配列に加える 61 sectionTitle.append(contentsOf: sectionTitle2)//**__該当部分1__** 62 } 63 return result 64 } 65 66 //今日と日付の配列の最後の日差分の日付配列をテーブルビューのsectionに表示する 67 68 func numberOfSections(in tableView: UITableView) -> Int // Default is 1 if not implemented 69 { 70 return sectionTitle.count 71 } 72 //// 73 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different 74 { 75 return sectionTitle[section] 76 } 77 78 79 // 80 let statusBarHeight = UIApplication.shared.statusBarFrame.height 81 82//セクションの項目 83 84 85 86 // チェックリストの項目とチェック状態 87 var checkListItem1: [String : Bool] = [ 88 "アイテム1" : true, 89 "アイテム2" : false, 90 "アイテム3" : true, 91 "アイテム4" : true, 92 "アイテム5" : false 93 ] 94 var checkListItem2: [String : Bool] = [ 95 "アイテム2-1" : false, 96 "アイテム2-2" : true, 97 "アイテム2-3" : true, 98 "アイテム2-4" : true, 99 "アイテム2-5" : false 100 ] 101 var checkListItem3: [String : Bool] = [ 102 "アイテム3-1" : true, 103 "アイテム3-2" : true, 104 "アイテム3-3" : true, 105 "アイテム3-4" : true, 106 "アイテム3-5" : false 107 ] 108 var checkListItem4: [String : Bool] = [ 109 "アイテム4-1" : true, 110 "アイテム4-2" : false, 111 "アイテム4-3" : true, 112 "アイテム4-4" : false, 113 "アイテム4-5" : false 114 ] 115 var checkListItem5: [String : Bool] = [ 116 "アイテム5-1" : true, 117 "アイテム5-2" : false, 118 "アイテム5-3" : true, 119 "アイテム5-4" : true, 120 "アイテム5-5" : true 121 ] 122 123 // 124 var tableData: [[String: Bool]] = [] 125 126 let tableView = UITableView() 127 128 // 129 override func viewDidLoad() { 130 super.viewDidLoad() 131// sectionを日付降順にソートする 132 sectionTitle = sectionTitle.sorted { $0 > $1 } 133 134 tableData = [checkListItem1, checkListItem2, checkListItem3, checkListItem4, checkListItem5] 135 136 // UITableView の作成 137 tableView.frame = CGRect( 138 x: 0, 139 y: statusBarHeight, 140 width: self.view.frame.width, 141 height: self.view.frame.height - statusBarHeight 142 ) 143 tableView.delegate = self 144 tableView.dataSource = self 145 self.view.addSubview(tableView) 146 } 147 148 // セルの作成 149 // 150 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 151 152 // tableDataの中から抽出 153 let sectionData = tableData[indexPath.section] 154 155 // キーで並び替え 156 let keys = sectionData.keys.sorted() 157 158 // キーの文字列を取得 159 let cellText = keys[indexPath.row] 160 161 // セルの作成とテキストの設定 162 let cell = UITableViewCell(style: .default, reuseIdentifier: "cell") 163 cell.textLabel?.text = cellText 164 165 /// 166 let cellIscheckd = sectionData[cellText] 167 168 // チェック状態が true なら、初めからチェック状態にする 169 if cellIscheckd == true { 170 cell.imageView?.image = UIImage(named: "checked") 171 } else { 172 cell.imageView?.image = UIImage(named: "unchecked") 173 } 174 175 return cell 176 } 177 178 // セルがタップされた時の処理 179 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 180 181 if let cell = tableView.cellForRow(at: indexPath) { 182 183 // タップしたセルのテキストを取得 184 let cellText = cell.textLabel?.text ?? "" 185 186 // 画像を切り替えと Dictonary の値を変更 187 if cell.imageView?.image == UIImage(named: "checked") { 188 189 self.tableData[indexPath.section][cellText] = false 190 191 cell.imageView?.image = UIImage(named: "unchecked") 192 } else { 193 194 self.tableData[indexPath.section][cellText] = true 195 cell.imageView?.image = UIImage(named: "checked") 196 } 197 198 // 選択状態を解除 199 cell.isSelected = false 200 } 201 } 202 203 204 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 205 let sectionData = tableData[section] 206 return sectionData.count 207 } 208} 209```swift3

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

いまいち仕様が理解しづらいのですが動くようにしてみました。前の質問で回答したgetDaysArrayToTodayの引数maxですがこれは単なる無限ループ防止用なので大きめの数字を適当に渡せばよいです。

所感ですがtableview展開云々の前にデータ構造の仕様をちゃんと詰めておくほう良さそうです。日付とcheckListItemの紐付けとか。モデルの部分ですね。テスト段階だからかもしれませんが今の感じだと並び順に依存してますのでかなり危ういです。

swift

1import UIKit 2 3class ViewController : UIViewController, UITableViewDelegate, UITableViewDataSource { 4 5 6 //文字列の日付をDate型に変換するクラス 7 class DateUtils { 8 class func dateFromString(string: String, format: String) -> NSDate { 9 let formatter: DateFormatter = DateFormatter() 10 formatter.dateFormat = format 11 return formatter.date(from: string)! as NSDate 12 } 13 14 class func stringFromDate(date: NSDate, format: String) -> String { 15 let formatter: DateFormatter = DateFormatter() 16 formatter.dateFormat = format 17 return formatter.string(from: date as Date) 18 } 19 } 20 21 22 //テーブルビューのsectionに表示する日付の配列 23 var sectionTitle = ["2016-01-23","2015-12-31","2015-01-12","2016-02-21","2016-12-20"] 24 25 //今日と日付の配列の最後の日差分の日付を配列にするメソッド 26 func getDaysArrayToToday(start:String,max:Int) -> [String] { 27 28// //テーブルビューのsectionに表示する日付の配列の最後の日 29// let dateArraymax = sectionTitle.max() 30// 31// // 日付の配列の最後の日をDate型に変換 32// let dateArraymaxdate = DateUtils.dateFromString(string: dateArraymax!, format: "yyyy/MM/dd") 33// 34// //今日と日付の配列の最後の日差 35// let now = NSDate() 36// let dateDifference = Int(now.timeIntervalSince(dateArraymaxdate as Date)/60/60/24) 37 38 var result:[String] = [] 39 let formatter = DateFormatter() 40 formatter.locale = NSLocale(localeIdentifier: "ja_JP") as Locale 41 formatter.dateFormat = "yyyy-MM-dd" 42 // 今日 43 let todayStr = formatter.string(from: Date()) 44 45 // 配列中の最大日が当日以下の場合は終了 46 if todayStr <= start { 47 return result 48 } 49 50 let startDate = formatter.date(from: start)! 51 var components = DateComponents() 52 let calendar = Calendar(identifier: Calendar.Identifier.gregorian) 53 54 //for i in 0 ..< max { 当日を含まないようにした 55 for i in 1 ..< max { 56 components.setValue(i,for: Calendar.Component.day) 57 let wk = calendar.date(byAdding: components, to: startDate)! 58 let wkStr = formatter.string(from: wk) 59 if wkStr > todayStr { 60 break 61 } else { 62 63 result.append(wkStr) 64 } 65 //?? let sectionTitle2 = getDaysArrayToToday(start: dateArraymax!,max: dateDifference) 66 67 //今日と日付の配列の最後の日差分の日付配列を元の日付配列に加える 68 //?? sectionTitle.append(contentsOf: sectionTitle2)//**__該当部分1__** 69 } 70 71 return result 72 } 73 74 //今日と日付の配列の最後の日差分の日付配列をテーブルビューのsectionに表示する 75 76 func numberOfSections(in tableView: UITableView) -> Int // Default is 1 if not implemented 77 { 78 return sectionTitle.count 79 } 80 //// 81 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different 82 { 83 return sectionTitle[section] 84 } 85 86 87 // 88 let statusBarHeight = UIApplication.shared.statusBarFrame.height 89 90 //セクションの項目 91 92 93 94 // チェックリストの項目とチェック状態 95 var checkListItem1: [String : Bool] = [ 96 "アイテム1" : true, 97 "アイテム2" : false, 98 "アイテム3" : true, 99 "アイテム4" : true, 100 "アイテム5" : false 101 ] 102 var checkListItem2: [String : Bool] = [ 103 "アイテム2-1" : false, 104 "アイテム2-2" : true, 105 "アイテム2-3" : true, 106 "アイテム2-4" : true, 107 "アイテム2-5" : false 108 ] 109 var checkListItem3: [String : Bool] = [ 110 "アイテム3-1" : true, 111 "アイテム3-2" : true, 112 "アイテム3-3" : true, 113 "アイテム3-4" : true, 114 "アイテム3-5" : false 115 ] 116 var checkListItem4: [String : Bool] = [ 117 "アイテム4-1" : true, 118 "アイテム4-2" : false, 119 "アイテム4-3" : true, 120 "アイテム4-4" : false, 121 "アイテム4-5" : false 122 ] 123 var checkListItem5: [String : Bool] = [ 124 "アイテム5-1" : true, 125 "アイテム5-2" : false, 126 "アイテム5-3" : true, 127 "アイテム5-4" : true, 128 "アイテム5-5" : true 129 ] 130 131 // 新規追加日用 132 var checkListItem: [String : Bool] = [ 133 "###アイテム1" : false, 134 "###アイテム2" : false, 135 "###アイテム3" : false, 136 "###アイテム4" : false, 137 "###アイテム5" : false 138 ] 139 140 // 141 var tableData: [[String: Bool]] = [] 142 143 let tableView = UITableView() 144 145 // 146 override func viewDidLoad() { 147 super.viewDidLoad() 148 149 let lastLaunch = sectionTitle.max()! 150 151 tableData = [checkListItem1, checkListItem2, checkListItem3, checkListItem4, checkListItem5] 152 153 let appendDays = getDaysArrayToToday(start: lastLaunch, max: 1200) 154 155 // 追加された日付分のcheckListItemをtableDataに追加 156 for _ in 0..<appendDays.count { 157 tableData.insert(checkListItem, at: 0) 158 } 159 160 sectionTitle.append(contentsOf: appendDays) 161 162 // sectionを日付降順にソートする 163 sectionTitle = sectionTitle.sorted { $0 > $1 } 164 165 //tableData = [checkListItem1, checkListItem2, checkListItem3, checkListItem4, checkListItem5] 上に移動 166 167 // UITableView の作成 168 tableView.frame = CGRect( 169 x: 0, 170 y: statusBarHeight, 171 width: self.view.frame.width, 172 height: self.view.frame.height - statusBarHeight 173 ) 174 tableView.delegate = self 175 tableView.dataSource = self 176 177 178 self.view.addSubview(tableView) 179 } 180 181 // セルの作成 182 // 183 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 184 185 // tableDataの中から抽出 186 let sectionData = tableData[indexPath.section] 187 188 // キーで並び替え 189 let keys = sectionData.keys.sorted() 190 191 // キーの文字列を取得 192 let cellText = keys[indexPath.row] 193 194 // セルの作成とテキストの設定 195 let cell = UITableViewCell(style: .default, reuseIdentifier: "cell") 196 cell.textLabel?.text = cellText 197 198 /// 199 let cellIscheckd = sectionData[cellText] 200 201 // チェック状態が true なら、初めからチェック状態にする 202 if cellIscheckd == true { 203 cell.imageView?.image = UIImage(named: "checked") 204 } else { 205 cell.imageView?.image = UIImage(named: "unchecked") 206 } 207 208 return cell 209 } 210 211 // セルがタップされた時の処理 212 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 213 214 if let cell = tableView.cellForRow(at: indexPath) { 215 216 // タップしたセルのテキストを取得 217 let cellText = cell.textLabel?.text ?? "" 218 219 // 画像を切り替えと Dictonary の値を変更 220 if cell.imageView?.image == UIImage(named: "checked") { 221 222 self.tableData[indexPath.section][cellText] = false 223 224 cell.imageView?.image = UIImage(named: "unchecked") 225 } else { 226 227 self.tableData[indexPath.section][cellText] = true 228 cell.imageView?.image = UIImage(named: "checked") 229 } 230 231 // 選択状態を解除 232 cell.isSelected = false 233 } 234 } 235 236 237 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 238 let sectionData = tableData[section] 239 return sectionData.count 240 } 241}

投稿2016/12/28 21:34

fromageblanc

総合スコア2724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kifu

2016/12/29 05:06

ありがとうございました。心から感謝します。データ構造等気がかりなんですが、日付でグループ分けして、新しい日付を前に表示するために安易な方法を取ってしまいました。何か良い方法があれば御教示をいただけますか。勉強したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問