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

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

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

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

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回答

286閲覧

UITableView 表示の仕組み

退会済みユーザー

退会済みユーザー

総合スコア0

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

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

Xcode

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

Swift

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

1グッド

0クリップ

投稿2017/09/26 00:53

編集2017/09/29 15:19
import UIKit class ViewController: UIViewController, UITableViewDelegate/*UITabBarDelegate*/,UITableViewDataSource { @IBOutlet weak var mytableView: UITableView! var kei = [String]() override func viewDidLoad() { super.viewDidLoad() mytableView.delegate = self mytableView.dataSource = self } @IBAction func addbtr(_ sender: Any) { let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: { (action:UIAlertAction!) -> Void in if let textFields = alert.textFields { for textField in textFields { self.kei.append(textField.text!) self.kei.append("cell 追加 ボタン") } self.mytableView.reloadData() } }) alert.addAction(okAction) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) alert.addAction(cancelAction) alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in textField.placeholder = "テキスト" }) alert.view.setNeedsLayout() self.present(alert, animated: true, completion: nil) } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return kei.count } func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { switch indexPath.row { case 1: return indexPath; default: return nil; } } func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { if kei.count > (indexPath.row + 1) { return nil } return indexPath } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = kei[indexPath.row] cell.textLabel?.textColor = UIColor.red cell.backgroundColor = UIColor.black if kei.count > (indexPath.row + 1) { // セルの選択不可にする cell.selectionStyle = UITableViewCellSelectionStyle.none cell.textLabel?.textColor = UIColor.black cell.backgroundColor = UIColor.yellow } else { // セルの選択を許可 cell.selectionStyle = UITableViewCellSelectionStyle.blue } return cell } func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) -> IndexPath? { if kei[indexPath.row] != "cell 追加 ボタン" { return [indexPath.row] }else /*if (self.kei.append("cell 追加 ボタン"))*/{ let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: { (action:UIAlertAction!) -> Void in if let textFields = alert.textFields { for textField in textFields { self.kei.insert(textField.text!, at:self.kei.count - 1) } self.mytableView.reloadData() } }) alert.addAction(okAction) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) alert.addAction(cancelAction) alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in textField.placeholder = "テキスト" }) alert.view.setNeedsLayout() self.present(alert, animated: true, completion: nil) return indexPath } } func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { self.kei.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) } } func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { let delete = UITableViewRowAction(style: .normal, title: "削除") {ation, index in self.kei.remove(at: (indexPath.row)) tableView.deleteRows(at: [indexPath], with: .fade) } delete.backgroundColor = .red let edit = UITableViewRowAction(style: .normal, title: "編集") { action, index in let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: { (action:UIAlertAction!) -> Void in if let textFields = alert.textFields { for textField in textFields { self.kei[indexPath.row] = textField.text! //self.kei.append(textField.text!) } self.mytableView.reloadData() } }) alert.addAction(okAction) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) alert.addAction(cancelAction) alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in textField.placeholder = "テキスト" }) alert.view.setNeedsLayout() self.present(alert, animated: true, completion: nil) print("edit") } edit.backgroundColor = .orange return [delete,edit] } func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { if kei.count > (indexPath.row + 1) { return true }else{ return false } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }

やりたいこと
**[+]**ボタンを押した時にアラートテキストで題名を入力し[cell 追加ボタンと]と一緒に追加したい

困っていること
前まではボタンからでもアラートテキストで入力した内容がcellに追加できたのですが色々コードを書き足している内に出来なくなりました。
それと[cell 追加ボタン]がどういう仕組みでtableViewに表示されているのかが分からないのでボタンの中に[cell 追加ボタン]の処理の書き方が分からなく困っています。

blakekei👍を押しています

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

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

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

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

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

ykws

2017/09/28 22:35

質問のタイトルは「UITableView の表示する仕組みについて」の方が適切な気がしました。
guest

回答2

0

ベストアンサー

それと[cell 追加ボタン]がどういう仕組みでtableViewに表示されているのかが分からないので+ボタンの中に[cell 追加ボタン]の処理の書き方が分からなく困っています。

UITableView の表示は func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell の部分で制御しています。
これは UITableView を表示するときに indexPath セルの位置を受け取り、そこに表示する UITableViewCell セルの内容を返し、それが画面上に反映される仕組みになっています。

この中で下記のように、配列 kei の値をセルの位置に合わせて表示しているのが読み取れると思います。

swift

1cell.textLabel?.text = kei[indexPath.row]

自分がやったこととしては宣言文をvar kei = Stringにするとcell上の"cell 追加 ボタン"をを消すことが出来ます。

なので、 @blakekei さんの試した方法で配列 kei の値を変更すれば UITableView の表示にも反映される理屈になります。

追加していく順番を3,2,1ではなく1,2,3のようにしたいのですがその場合どうしたらいいのでしょうか?
appendにすると1,2,3にはなるのですがそうすると[cell 追加 ボタン]の下に追加されてしまいます。

これを踏まえて、表示順は配列のデータ順なので、配列の末尾の前にデータを追加していけば期待するデータ順となり、表示順もそのようになります。

swift

1self.kei.insert(textField.text!, at:self.kei.count - 1)

意味合いの異なるセルはセクションを分けるのも方法の一つだと思います。
そうすると可変の配列と固定の配列を別で管理することになるので、 append が有効になります。

参考: UITableView Section の設定

続いて、セルのタップ制御を現状は下記のように最後のセルしか反応しないように書いていますので、

swift

1kei.count > (indexPath.row + 1)

「cell 追加 ボタン」全てに反応させるには、例えば、以下のような条件に変更すれば反応します。

swift

1kei[indexPath.row] != "cell 追加 ボタン"

ただ、 UI 的に不自然な気はします。
セルの追加は画面右上の「+」ボタンだけで十分では?

投稿2017/09/28 22:34

編集2017/09/29 03:53
ykws

総合スコア1236

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

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

退会済みユーザー

退会済みユーザー

2017/09/28 23:26

そのようなやり方があったんですね! 私場合、昨日ダメごとでこのようにコードを書いたら1,2,3,4と表示させることが出来ました。 self.kei.insert(textField.text!, at: indexPath.row) でも@ykwsさんのコードの方がコードとして正しそうなのでself.kei.insert(textField.text!, at:self.kei.count - 1)を使いたいと思います。 それとなんですが、今の時点だと一番下の[cell 追加 ボタン]でしかcellを追加できないのですが、どうすれば他の[cell 追加 ボタン]でもcellを追加できるのでしょうか? 私なりに考えられることしてはfunc didSelectRowAtIndexPathのif 文のelseの部分に self.kei.append("cell 追加 ボタン")を関連させることが出来れば全ての[cell 追加 ボタン]にcell追加する機能を付けれると思うのですがどのように関連させればいいか分からないのでもし宜しければ教えて頂けないでしょうか?
ykws

2017/09/29 00:57

回答に追記しました。 基本的にはその考え方であっています。ただ現状はセルの活性状態を制御しているので、その部分の条件を変えるのが妥当だと思いました。
ykws

2017/09/29 03:54

typo があったので回答編集しました。 当然、追記してもらったように配列外アクセスになりますね。
退会済みユーザー

退会済みユーザー

2017/09/29 03:55

さそっく試して見たのですがビルドと+ボタンで追加するまでは大丈夫だったのですが[cell 追加 ボタン]で追加しようとすると画像のようなエラーが出てきたのですが他にも何か書き直さないといけなかったのでしょうか?
退会済みユーザー

退会済みユーザー

2017/09/29 04:09

kei[indexPath.row] != "cell 追加 ボタン" 上記のようにするとエラーは取れましたがやはり黄色の部分の[cell 追加 ボタン]は反応しませんでした。 確かにcellを追加するだけなら[+]だけで十分だと思うのですが私としてはブロックごとに小分けにして、そのブロックで何か追加し忘れてもそのブロックにボタンがあるとあとでそのブロックにまたcellを追加できるのでその方が使い勝手がいいのかなと思いこのようにしたいと思いました。
ykws

2017/09/29 04:23

willSelectRowAt と didSelectRowAtIndexPath の両方の条件を変更しても反応しないですか?
退会済みユーザー

退会済みユーザー

2017/09/29 04:46

fun didSelectRowAtIndexPathしかやっていませんでした。なのでwillSelectRowAtにもそのようにして見たところ無事にやりたいことが出来ました。 それと全く別な事なんですが@ykwsさんはswiftをどのように勉強しているのでしょか?毎回毎回、ものすごく分かりやすく、私の質問に対して全部回答してくださるのでもし宜しければ何を参考に勉強しているのか教えていただけると嬉しいです。一応私としては本気ではじめるiphoneアプリ開発などの本を3冊ほど購入し、勉強しているのですがこのような私の質問に対しては本には全然書いてなかったのでお聞きしたく質問しました。
ykws

2017/09/29 17:03

Swift に関しては「Swift実践入門」で理解を深めました。ただ、この辺りの基本的な考え方は iOS の初期からそれほど変わってはいないと思うので、それまでの iPhone / iOS / Objective-C の経験が糧になっているなと感じています。改めて本棚を見返し、書籍をまとめてみました。参考までに。 http://ykawashi7.hatenablog.com/entry/2017/09/30/015609
退会済みユーザー

退会済みユーザー

2017/10/01 02:59

昨日早速教えて頂いた[Swift実践入門]の本を購入しました。hatenaブログで紹介していた他の書籍も購入したかったのですがまだ学生なのでとりあえず[Swift実践入門]を理解してからまた購入しようと思います。 それとなんですがもし宜しければtableViewのチェックマークについて質問しましたので教えて頂けないでしょうか?qiita等で調べチェックマークはつけることは出来たのですが消すことが出来なく困っています。 お忙しと思いますがもし宜しくお願い致します。 https://teratail.com/questions/94578
退会済みユーザー

退会済みユーザー

2017/10/02 00:04

let cell = tableView.cellForRow(at: indexPath) if cell!.accessoryType == .checkmark{ cell!.accessoryType = .none }else{ cell!.accessoryType = .checkmark } func didSelectRowAtIndexPathで上記のようなコードを追加したところ[cell 追加 ボタン]にチェックマークをつけたり、消したりは出来るようになったのですが[cell 追加 ボタン]と[+]ボタンで最初に追加したcell以外だけにチェックマークをつけたい場合どのようなif文を書けばいいのでしょうか? 条件が二つなのでどうif文を書けばいいか分からなく困っています。
ykws

2017/10/02 02:17

教えてもらった質問の方に回答しました。
退会済みユーザー

退会済みユーザー

2017/10/19 07:15

先日の質問で教えて頂いた構造体を自分なりに使ってみたのですがコードのエラーはないのですがチェックマークがやっぱりcellを追加するとずれてしまうのでもし宜しければもう少し詳しく教えて頂けないでしょうか? 一応cellのチェックマークずれについて新しく質問を立てました。 https://teratail.com/questions/96997
ykws

2017/10/19 13:21

@fuzzball さんの回答がすでに付いていて正しいと思いますので、補足のコメントをしました。
退会済みユーザー

退会済みユーザー

2017/10/22 04:27

すいません、再度お聞きしたいことがあるのですがtableViewのスワイプ処理なんですが一般的右から左にスワイプする処理は出来るのですが左から右にスワイプする方法が分からなくて困っています。一応私なりにappleのドキュメントを参考にしleadingSwipeActionsConfigurationForRowAtを使って書いてみたのですがこれってios11じゃないとエラーが出るのでしょうか? もし宜しければ教えて頂けないでしょうか? 一応スワイプに関する処理について質問を立てました。 https://teratail.com/questions/97229
ykws

2017/10/23 00:31

教えてもらった質問の方に回答しました。
guest

0

今日自分も同じことで困っていました。でも解決できたので自分なりのやり方でアドバイスするので参考にして見てください。自分がやったこととしては宣言文をvar kei = [String]()にするとcell上の"cell 追加 ボタン"をを消すことが出来ます。その次にalerttextの中の
self.kei.insert(textField.text!, at:0)の部分をもう一行追加し、self.kei.insert("cell 追加ボタン 追加", at: 1)にするとおそらくやりたいことが出来ると思います。

投稿2017/09/27 13:33

blakekei

総合スコア35

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

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

退会済みユーザー

退会済みユーザー

2017/09/28 01:53

教えて頂いた通りにやったら出来ました。それとなんですがcell追加時に[apple 製品について 題名]と[cell 追加 ボタン]の間にcellを追加させたくself.kei.insert("cell 追加ボタン 追加", at: 1)にしたら間に追加することは出来たのですが追加していく順番を3,2,1ではなく1,2,3のようにしたいのですがその場合どうしたらいいのでしょうか?appendにすると1,2,3にはなるのですがそうすると[cell 追加 ボタン]の下に追加されてしまいます。
blakekei

2017/09/28 02:28

すいません。私自身もまだswiftについて勉強している途中なのでそこまではわかりません。しかし、私もそれについて気になるので@haruka-tさんに何度か回答をしている@ykwsさん にお聞きして見てはどうでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問