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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

2回答

251閲覧

tableViewについてあれこれ

退会済みユーザー

退会済みユーザー

総合スコア0

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/05/11 02:49

編集2018/05/14 15:41

swift

1//ViewController.swift 2import UIKit 3 4class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate{ 5 6 @IBOutlet weak var mytableView: UITableView! 7 8 //構造体 9 let initialItems: [String] = [] 10 var kei: [Cell] = Array() 11 12 var item: [String] = [] 13 var cnt = 0 14 var itemTotal: [[String]] = [[]] 15 16 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 17 if (itemTotal.count == 0 18 || itemTotal.count > 0 && itemTotal[0].count == 0) { 19 return 0 20 } else { 21 return itemTotal.count 22 } 23 } 24 25 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 26 let cell = UITableViewCell() 27 let index = itemTotal.count - 1 - indexPath.row 28 let item = itemTotal[index] 29 30 guard item.count > 0 else { 31 return cell 32 } 33 34 var labels: [UILabel] = [] 35 //labelについて 36 for i in item { 37 let label = UILabel() 38 label.backgroundColor = UIColor.darkGray 39 label.text = i 40 41 42 // textLabel という名前の変数に格納された UILabel にフォントサイズの自動調整を設定します。 43 label.adjustsFontSizeToFitWidth = true 44 label.minimumScaleFactor = 10.0 45 //丸みに対して 46 label.layer.cornerRadius = 5 47 label.layer.masksToBounds = true 48 cell.contentView.addSubview(label) 49 labels.append(label) 50 } 51 52 var preLabel: UILabel? = nil 53 for l in labels { 54 55 l.translatesAutoresizingMaskIntoConstraints = false 56 if (preLabel == nil) { 57 l.leftAnchor.constraint(equalTo: cell.contentView.leftAnchor, constant: 12).isActive = true 58 } else { 59 l.leftAnchor.constraint(equalTo: preLabel!.rightAnchor, constant: 20).isActive = true 60 } 61 cell.contentView.heightAnchor.constraint(equalTo: l.heightAnchor, multiplier: 1).isActive = true 62 preLabel = l 63 } 64 65 66 return cell 67 } 68 69 70 @IBAction func addcellbtr(_ sender: Any) { 71 72 alertnormal() 73 } 74 75 func alertnormal(){ 76 // テキストフィールド付きアラート表示 77 78 let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) 79 80 // OKボタンの設定 81 let okAction = UIAlertAction(title: "OK", style: .default, handler: { 82 (action:UIAlertAction!) -> Void in 83 84 // OKを押した時入力されていたテキストを表示 85 if let textFields = alert.textFields { 86 87 // アラートに含まれるすべてのテキストフィールドを調べる 88 for textField in textFields { 89 self.item.insert(textField.text!, at: 0) 90 self.mytableView.insertRows(at: [IndexPath(row: 0, section: 0)],with: UITableViewRowAnimation.automatic) 91 print(textField.text!) 92 } 93 self.mytableView.reloadData() 94 } 95 }) 96 alert.addAction(okAction) 97 98 // キャンセルボタンの設定 99 let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 100 alert.addAction(cancelAction) 101 102 // テキストフィールドを追加 103 alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in 104 textField.placeholder = "テキスト" 105 }) 106 107 alert.view.setNeedsLayout() // シミュレータの種類によっては、これがないと警告が発生 108 109 // アラートを画面に表示 110 self.present(alert, animated: true, completion: nil) 111 112 } 113 114 115 func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { 116 117 let edit = UIContextualAction(style: .normal,title: "追加", handler: { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in 118 119 let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) 120 121 // OKボタンの設定 122 let okAction = UIAlertAction(title: "OK", style: .default, handler: { 123 (action:UIAlertAction!) -> Void in 124 125 // OKを押した時入力されていたテキストを表示 126 if let textFields = alert.textFields { 127 128 // アラートに含まれるすべてのテキストフィールドを調べる 129 for textField in textFields { 130 self.item.insert(textField.text!, at: 0) 131 self.itemTotal[self.cnt] = self.item 132 133 if self.item.count % 5 == 0, self.itemTotal[0].count > 1 { 134 self.cnt += 1 135 self.itemTotal.append([]) 136 self.item = [] 137 print(textField.text!) 138 //self.Gesture() 139 //self.doubleclic() 140 } 141 self.mytableView.reloadData() 142 } 143 } 144 }) 145 alert.addAction(okAction) 146 147 // キャンセルボタンの設定 148 let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 149 alert.addAction(cancelAction) 150 151 // テキストフィールドを追加 152 alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in 153 textField.placeholder = "テキスト" 154 }) 155 156 157 alert.view.setNeedsLayout() // シミュレータの種類によっては、これがないと警告が発生 158 159 // アラートを画面に表示 160 self.present(alert, animated: true, completion: nil) 161 print("edit") 162 163 success(true) 164 }) 165 166 edit.backgroundColor = .blue 167 168 return UISwipeActionsConfiguration(actions: [edit]) 169 } 170 171 172 173 // trueを返すことでCellのアクションを許可しています 174 func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 175 176 if item.count > (indexPath.row + 1) { 177 return true 178 }else{ 179 return false 180 } 181 } 182 183 184 //注意 185 186 func alert(){ 187 // テキストフィールド付きアラート表示 188 189 let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) 190 191 // OKボタンの設定 192 let okAction = UIAlertAction(title: "OK", style: .default, handler: { 193 (action:UIAlertAction!) -> Void in 194 195 // OKを押した時入力されていたテキストを表示 196 if let textFields = alert.textFields { 197 198 // アラートに含まれるすべてのテキストフィールドを調べる 199 for textField in textFields { 200 self.item.insert(textField.text!, at: 0) 201 self.itemTotal[self.cnt] = self.item 202 203 if self.item.count % 5 == 0, self.itemTotal[0].count > 1 { 204 self.cnt += 1 205 self.itemTotal.append([]) 206 self.item = [] 207 print(textField.text!) 208 //self.Gesture() 209 //self.doubleclic() 210 } 211 self.mytableView.reloadData() 212 } 213 } 214 }) 215 alert.addAction(okAction) 216 217 // キャンセルボタンの設定 218 let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 219 alert.addAction(cancelAction) 220 221 // テキストフィールドを追加 222 alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in 223 textField.placeholder = "テキスト" 224 }) 225 226 alert.view.setNeedsLayout() // シミュレータの種類によっては、これがないと警告が発生 227 228 // アラートを画面に表示 229 self.present(alert, animated: true, completion: nil) 230 231 } 232 233 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 234 return 40 235 } 236 237 override func viewDidLoad() { 238 super.viewDidLoad() 239 240 mytableView.delegate = self 241 mytableView.dataSource = self 242 mytableView.estimatedRowHeight = 60 243 //mytableView.backgroundColor = UIColor(red: 0.0, green: 0.8, blue: 1.0, alpha: 0.1) 244 245 for item in initialItems { 246 kei.append(Cell(item: item, cellcolor: false)) 247 } 248 } 249 250 251 252 override func didReceiveMemoryWarning() { 253 super.didReceiveMemoryWarning() 254 // Dispose of any resources that can be recreated. 255 } 256 257 258}

今やっている事

まずボタンをタップした時に題名となるcellとその中身となるcellを挿入しようとしています。
中身となるcellはスワイプによって編集できるようにしています。

困っている事
最初に題名となるセルを追加しようとコードを加えたのですが実行時にはエラーは起きないのですが実際にアラートを呼び出しOKとタップすると落ちてしまいます。
エラーはsignal SIGABRTによるものです。

swift

1//cell.swift 2struct Cell { 3 //var category: String 4 //var name: String 5 var title: String 6 var item: String 7 var cellcolor: Bool 8 var cnt = 0 9 10 init(item: String,cellcolor: Bool) { 11 self.init(title: item,item: item,cellcolor: cellcolor) 12 self.item = item; 13 self.cellcolor = cellcolor; 14 //self.itemTotal = item; 15 } 16 17 init(title: String,item: String,cellcolor: Bool) { 18 self.title = title; 19 self.item = item; 20 self.cellcolor = cellcolor; 21 //self.itemTotal = item; 22} 23 24} 25

最新のコードです。
構造体でtitleセルとdetailセルをグループ化しようとしています。

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

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

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

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

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

guest

回答2

0

ベストアンサー

原因となっているのは、

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if (itemTotal.count == 0 || itemTotal.count > 0 && itemTotal[0].count == 0) { return 0 } else { return itemTotal.count } }

でitemTotalのサイズを数えていますが、

func alertnormal(){ ...(省略) // アラートに含まれるすべてのテキストフィールドを調べる for textField in textFields { self.item.insert(textField.text!, at: 0) self.mytableView.insertRows(at: [IndexPath(row: 0, section: 0)],with: UITableViewRowAnimation.automatic) print(textField.text!) } self.mytableView.reloadData()

ここではitemTotalにデータを追加していないため、
self.mytableView.insertRowsで行を追加しようとしていますが、
itemTotalの数と合わなくなっていることが原因と考えられます。

解決方法としては、alertnormalでもitemTotalにデータを追加する必要があります。

とりあえずの回避方法としては

func alertnormal(){ ...(省略) // アラートに含まれるすべてのテキストフィールドを調べる for textField in textFields { self.item.insert(textField.text!, at: 0) if (self.cnt != 0) { self.itemTotal.append([]) } self.itemTotal[self.cnt].append(textField.text!) self.tableView.insertRows(at: [IndexPath(row: 0, section: 0)],with: UITableViewRowAnimation.automatic) self.cnt += 1 print(textField.text!) } self.tableView.reloadData()

のような形にするとエラーは出なくなりました。

投稿2018/05/13 22:30

newmt

総合スコア1277

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

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

退会済みユーザー

退会済みユーザー

2018/05/14 05:03

alertnormalにitemTotalのデータを追加してしまうとラベルとして追加されてしまうのでそれを避ける為にitemTotalを使わないようにしていたのですが、ご教示して頂いたコートですとラベルとして追加されてしまうのでただのテキストとしてセルに追加することは出来ないのででしょうか? 私としてはtitleとしてのセルとdetailとなるセルを区別にする為にstructで使ってグルーピングしたいと思っているのですが配列の入ってる今回のようなコードだとどう構造体を使って書けばいいか分からないでいるのでご教示いただけないでしょうか?
退会済みユーザー

退会済みユーザー

2018/05/14 15:36 編集

構造体を使ってtitleとなるセルとdetailとなるセルをグループにして表示させようとしているのですが下記のコードをどうstructの中に下記入れればいいか分からなくて困っています。 var item: [String] = [] var cnt = 0 var itemTotal: [[String]] = [[]] イメージとしては apple商品         ←titleセル [iPhone] [iPad] [iMac] [Macbook] [Apple Watch] ←detailセル このような感じになります。以前、構造体でセルのグループ分けの仕方は知っているのですがラベルのあるセルでは作ったことがなかったので教えて頂けると幸いです。
newmt

2018/05/14 21:23

やられたいことから考えると、セルで分けるのではなくセクションを使った方が良いのではないかと思います。以下の内容が参考になるかと思います。 http://docs.fabo.io/swift/uikit/019_sectionuitableview.html 構造体を使うとなると struct Product { let title: String let detail: [String] } として var products: [Product]という配列で管理するかなと思います。
退会済みユーザー

退会済みユーザー

2018/05/15 05:20

懇切に教えていただき有難うございます。 配列の部分でのエラーはなくなりました。 それでなんですがitemの部分をproductsに置き換えているのですがitemTotalの部分は何に置き換えて行けばいいのでしょうか?それともitemTotalはそのまま残す感じでしょうか? var cnt = 0はカウントする為に残しましたがitemTotalはどうすればいいか分からないのですご教示願いたいです。
newmt

2018/05/15 21:12

私のイメージですと、let detail: [String]がitemになり、var products: [Product]がitemTotalのイメージです。cntは配列の順番と行の順番が連動している(indexPathから取得できる)ので特に必要ないのかなと思いました。
退会済みユーザー

退会済みユーザー

2018/05/16 05:37

https://teratail.com/questions/126260 私なりに置き換えてみたのですが上手く動かなかったので見てもらえませんか?
退会済みユーザー

退会済みユーザー

2018/05/16 09:27 編集

numberOfRowsInSectionのメソッドで多次元配列のitemTotalの部分いprodauctsを入れるとエラーが起こるのですがどう対処すれば良いのでしょうか?
guest

0

まずは Xcode のデバッガを利用して、 OK をタップした後の処理をステップ実行し、どのコードが原因か絞り込むのが良いと思います。

投稿2018/05/11 02:58

ykws

総合スコア1236

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

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

退会済みユーザー

退会済みユーザー

2018/05/11 03:17

デバッグを見てみたのですがあまり理解できなかったです。 でも多分、cellForRowAtの中にラベルに関するコードのせいでエラーが起きてるんじゃないんかと思っています。
退会済みユーザー

退会済みユーザー

2018/05/11 04:01

題名となるセルに中身となるラベルの処理を呼ばれないようにするにはどうしたらいいですか? 多分、cellForRowAtの中の処理が呼ばれてエラーが起きたのではないかと思います。
newmt

2018/05/11 08:03

signal SIGABRT以外に何かメッセージは出ていませんか? 「多分、cellForRowAtの中の処理が呼ばれてエラーが起きたのではないかと思います。」 これはブレークポイントを設定した場合に呼ばれていたということでしょうか?その場合、どこの行でエラーが発生しているか特定できていますでしょうか?
退会済みユーザー

退会済みユーザー

2018/05/13 07:22

メッセージはsignal SIGABRTしか出ていないと思われます。 私が思うには今回のアラートはただ入力したものをcellに反映させたいだけなのでcellForRowAt内でのlabelの処理で落ちたのかなと思います。 実際に、旧アラート(挿入時にlabelとして挿入されるアラート)では問題はありませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問