TableViewについて

#TableViewについて
表題の通りですが、初心者にとってはTableViewはわかりにくいところが多かったので、メモにしておこうと思います。よろしければ、同じような初心者の方も参考にしてみてください。
間違っていたら、お手数ですがお知らせください。

バージョンは下記の通りです。
Xcode　11.5
Swift　5.2.4



##TableViewとは

この機能はゲーム等、色々なところで見かけます。
iPhoneのアプリで言うと、メモとかに使われているもので、垂直方向に値等をストックしていく機能を持っています。なので、配列と併せて使うと効果を発揮します。



##TableViewを設置する
Storyboard上にTableViewを画面に設置してその上にTableViewCellを重ねるように設置します。文字入力用としてtextfieldも追加します。

　　TableView・・・TableViewの機能の土台となる部分
　　TableViewCell・・・値を垂直方向に貯めていくセルを生成する部分

![スクリーンショット 2020-06-27 21.58.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657690/02a67362-93d8-4b74-1aee-5cb7e1e92873.png)

また、TableViewCellはStoryboardのAttributes inspectorの中にあるidentifierは空白になっているので、ID名を入れる必要があります。

![スクリーンショット 2020-06-27 22.59.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657690/cbbe630b-0268-7380-c7bd-cc181af50be8.png)


##UIとプログラムをつなげる
Storyboard上からCtrlキーを押しながらプログラムにつなげて変数名を付けます。
さらにデータを貯める配列も宣言します。

```swift
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var tableView: UITableView!
    var tableArray :[String] = [] //var tableArray = [String]()
```

##TableViewプログラム記述（プロトコル）
プロトコルを宣言します。

　　①UITableViewDelegate・・・TableView関係のプロトコル
　　②UITableViewDataSource・・・TableView関係のプロトコル
　　③UITextFieldDelegate・・・TextField関係のプロトコル

このままだとプロトコルが使えないので、それぞれviewDidLoad()内で宣言して、UIViewControllerで使えるようにします。
　　①tableView.delegate = self
　　②tableView.dataSource = self
　　③textField.delegate = self

```swift
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate {
    
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var tableView: UITableView!
    var tableArray :[String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        textField.delegate = self
    }
```

記述が終わると、Xcodeから関数がないと言われるので、fixを選択すると下記の関数が自動で追加されます。この2つの関数がtableViewを動かす最低限の関数だから自動的に追加されるのだと思います。

① 、②のプロトコルからの関数・・・tableViewのセルの数等を決める関数

```swift

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
```

① 、②のプロトコルからの関数・・・生成したセルのプロパティを決める関数

```swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
```

##TableViewプログラム記述（関数）
自動で追加された２つの関数を作っていきます。
どちらの関数も　->　が入っているので、最後にreturn 〇〇で終了し、値を返します。（※但し、①はreturnを省略しても大丈夫です。）

上記①のプロトコルからの関数は数の指定なので、tableViewの値を貯める数を指定します。個人的にはtableViewは配列と併せて使うものだと思っていますので、値は配列の数だけ貯めるように指定します。

```swift

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        tableArray.count
    }
```

上記②のプロトコルからの関数はそれぞれの引数にクラスのUITableView、構造体のIndexPathを宣言します。

また、①と同様にクラスを引数に入れていますが、こちらではUITableViewクラスのプロパティを設定する必要があります。

その為、UITableViewクラスの関数等の使用は初なので、プロトコルの関数内にて、UITableViewクラスのインスタンス化を行います。

withIdentifierで使われるIDはセルについてなので、当然Storyboard上で設定したTableViewCellのID名とし、UITableViewクラスのプロパティと繋げます。

cellForRowAt indexPath: IndexPathは値が入り生成されたセルの場所を示します。
プロトコル内の引数を同じにして、セルを生成した場所 ＝ セルの保存場所とします。

```swift

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let tableCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        tableCell.textLabel?.text = tableArray[indexPath.row]
        return tableCell
    }
```

##textfieldプログラム記述（関数）


textfieldに入力された値を、tableViewの配列に蓄積させます。

tableArray.append(textField.text!)を記述することで、
tableArrayに値が追加　→ tableArrayの数分だけセルの数を追加　→　tableArrayの値をセルに追加となる。

resignFirstResponder()は実機等で文字のreturnキーを押した時に、キーボードを非表示にする機能です。

-> Boolなのでtrueかfalseで返します。



```swift

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        tableArray.append(textField.text!)
        textField.resignFirstResponder()
        textField.text = ""
        tableView.reloadData()
        return true
    }
```

##ビルドしてみる
ここまででビルドするとこんな感じです。

![スクリーンショット 2020-06-27 13.36.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657690/fee2b0e6-4b87-6f2f-f547-e8bb2aee6434.png)

なんか殺風景すぎるけど、ここにセルの高さ指定、イメージ挿入、背景追加、値の保存、タップした時の動きとか、色々機能を追加することで形にはなると思います。


以上ですが、UIのプラスボタンからUITableViewControllerを持ってくれば、より細かい機能を実装した状態で設置できますので、そっちの方で設置する方が早いと思います。