Swiftのテーブルビューコントローラでの作業
Reinder de Vriesによって2020年8月3日にiOSのアプリ開発で作成されました
このチュートリアルでは、テーブルビューコントローラがどのように機能し、どのように使用できるかを段階的に オブジェクト指向プログラミング、委任、テーブルビューの舞台裏のメカニズムに飛び込むことによって、UITableViewController
の完全な範囲に入ります。
テーブルビューコントローラは、構造化された繰り返し可能な情報を垂直リストに表示します。 IOSアプリでUITableViewController
クラスを使用して、テーブルビューコントローラを構築します。
テーブルビューコントローラを使用することは、サブクラス化、委任設計パターン、ビューの再利用など、いくつかの重要なiOS開発概念を使用することも意味します。
これは、プロと実用的なiOS開発者のために重要です(あなた!)テーブルビューコントローラでの作業をマスターする。 このような多面的なUIコンポーネント、UITableViewController
のような作業に慣れたら、iOS開発の他のより複雑な側面も意味をなさなくなります。
で潜ろう!
- テーブルビューコントローラの動作方法
- 単純なテーブルビューコントローラの設定
- テーブルビューコントローラのデータソースのコーディング
- テーブルビューコントローラへのセルの提供
- ユーザーの操作への応答
- 続きを読む
テーブルビューコントローラの動作方法View Controller Works
以前にIosアプリを使用したことがある場合は、以前にTable View Controllerを使用していました。 彼らはiOSアプリで頻繁に使用されています!
テーブルビューコントローラの例を次に示します:
テーブルビューコントローラには、通常、次の可視コンポーネントがあります:
- 画面に表示されるユーザーインターフェイスコンポーネントまたはビューであるテーブルビュー。 テーブルビューは、
UIScrollView
のサブクラスであるUITableView
クラスのインスタンスです。 - テーブルビューに表示される反復可能な行またはビューであるテーブルビューセル。 テーブルビューセルは
UITableViewCell
クラスのインスタンスであり、そのクラスは多くの場合、カスタムテーブルビューセルを作成するためにサブクラス化されます。
テーブルビューコントローラは、これらのコンポーネントの使用にも依存しています。:
- テーブルビューのレイアウトを管理し、ユーザー操作イベントに応答するテーブルビューデリゲート。 テーブルビューデリゲートは、
UITableViewDelegate
クラスのインスタンスです。 - テーブルビューのセルやセクションなど、テーブルビュー内のデータを管理するテーブルビューデータソース。 データソースは、
UITableViewDataSource
クラスのインスタンスです。
ナビゲーションコントローラは、テーブルビューと後続のビューコントローラとの間のナビゲーションを可能にし、テーブルビューの上にナビゲーションバーを表示するために、テーブルビューコントローラと組み合わせて使用されることがよくあります。
テーブルビューコントローラでの作業の最も興味深い部分は、テーブルビューコントローラ自体です! どうやって?
モデル-ビュー-コントローラのアーキテクチャに精通していますか? Model-View-Controllerアーキテクチャによると、テーブルビューとテーブルビューセルはビューであり、テーブルビューコントローラはコントローラです。
ビューは、ユーザーインターフェイス(UI)を使用して、ユーザーに目に見えるように情報を表示する役割を果たします。 コントローラは、ロジックの実装、データの管理、意思決定を行う責任があります。 別の言い方をすると、コントローラは見えませんが、そこにあり、ビューを通して見るものを管理します。
アプリでテーブルビューコントローラを使用する場合、UITableViewController
クラスをサブクラス化しています。 9268>クラス自体はUIViewControllerのサブクラスです。
連絡先情報を表示するテーブルビューコントローラの例のクラス階層を次に示します:
- サブクラス
ContactsTableViewController
- サブクラスのインスタンス
UITableViewController
- サブクラス
UIViewController
- サブクラス
- サブクラスのインスタンス
オブジェクト指向プログラミング(OOP)の原則に従って、classRaceCar
がclassVehicle
をサブクラス化すると、maxSpeed
やdrive()
などのスーパークラスのプロパティと関数が継承されます。
Vehicle
クラスはRaceCar
のスーパークラスと呼ばれます。 この原則は継承と呼ばれます。
それはすることができます! このように考えてみてください: table view controllerが正常に動作するためには、たくさんのコードを継承する必要があるため、すべてのコードを自分で記述する必要はありません。 クラス階層とOOPは、その継承を構造化するためにあります。
テーブルビューコントローラを使用せずにテーブルビューを操作できます。 View controllerにUITableView
を追加し、table view delegate関数とdata source関数の実装を提供するだけで完了です。
UITableViewController
クラスは、これらのテーブルビューデリゲートおよびテーブルビューデータソース関数の既定の実装を提供します。 これは、テーブルビューコントローラを使用する際の重要な側面です。
このチュートリアルの次の章で説明するように、これらの関数を独自の実装でオーバーライドします。 これにより、テーブルビューコントローラをカスタマイズできます。
iOSアプリの構築方法を学ぶ
iOS14とSwift5を使い始める
iOS開発コースにサインアップし、Swift5とXcode12で優れたiOS14アプリを構築する方法を学びます。
単純なテーブルビューコントローラの設定
さて、それをすべて実践しましょう。 このセクションでは、単純なテーブルビューコントローラを構築します。 あなたはそれを動作させるために必要な関数を実装しようとしている、と私は我々が一緒に行くように彼らがどのように動作するかを説明します。 移動を取得してみましょう!
XcodeでUiを操作するには、3つの異なるアプローチを使用できます:
- つまり、手作業でコーディングする
- Interface BuilderでUiを設定し、Xibを介してSwiftコードと接続する
- Storyboards
- を使用してInterface BuilderでUiとその遷移を設定する
- (技術的にはSwiftUIも使用できますが、テーブルビューコントローラについては、このチュートリアルの範囲を超えています。)
Uiを手作業でコード化するのは面倒で非生産的です。 あなたがストーリーボードに注意していない場合、彼らは開発者から複雑さを隠してしまいます。 彼らは舞台裏でどのように動作するかを正確に把握しながら、私たちは、ストーリーボードで作業するつもりです。
まず、File→New→Project…を使用して新しいXcodeプロジェクトを作成します。 アプリテンプレートを選択し、インターフェイスのStoryboardとライフサイクルのUIKitアプリデリゲートを選択してくださ
次に、次の手順を実行します:
- プロジェクトナビゲーターでプロジェクトを右クリックし、新しいファイルを選択します…
- Cocoa Touchクラステンプレート(iOS)を選択します
-
UITableViewController
を選択します - のサブクラス
ContactsTableViewController
- クラス名
ContactsTableViewController
- XIBファイルを作成します
- 最後に[次へ]をクリックして、他のSwiftファイルと一緒にファイルを保存します
最後に、これを行います:
-
Main.storyboard
に移動し、既存のView Controllerシーンを削除します - ライブラリを介して新しいテーブルビューコントローラをストーリーボードに追加します
- テーブルビューコントロー
ContactsTableViewController
これで終わりです! これで、プロジェクトのストーリーボード内にテーブルビューコントローラがあり、それをContactsTableViewController
Swiftクラスに接続しました。
ご想像のとおり、ContactsTableViewController
クラスはUITableViewController
のサブクラスです。 Swiftファイルの一番上のクラス宣言でそれを見ることができます。
class ContactsTableViewController: UITableViewController { ···
この構文は、クラスContactsTableViewController
がUITableViewController
のサブクラスであることを意味します。Optionキーを押しながら”UITableViewController”を右クリックすると、クラス宣言でUITableViewController
がUIViewController
のサブクラスであり、UITableViewDelegate
およびUITableViewDataSource
プロトコルに準拠していることがわかります。
それがテーブルビューコントローラの力です! これは、テーブルビューを作成するための個々のコンポーネントを提供するだけでなく、コントローラもデフォルトの実装を提供します。 そのため、テーブルビューで空のビューコントローラを作成するのではなく、UITableViewController
をサブクラス化します。
この時点で、Command-R
または再生ボタンを使用してアプリを実行すると、空のテーブルビューコントローラが画面に表示されます。
ところで、それはなぜですか? まだ何もコード化していません! これは、table view controllerにはデフォルトの実装があり、画面に空のセルが表示されるだけであるためです。 ニート!
Xcodeのバージョンに応じて、scene delegateを使用してアプリプロジェクトの初期view controllerを設定しました。 詳細はこちら:XcodeのScene Delegate
XIBとNIBは基本的に同じものです-レイアウト情報が含まれています。 XIBにはXML形式がありますが、NIBにはバイナリ形式があります。 XMLはアプリをビルドするときにバイナリにコンパイルされるため、UIKitの関数は常に「nib」について話し、Xcodeは常に「xib」と呼んでいます。
テーブルビューコントローラのデータソースのコーディング
テーブルビューコントローラがセットアップされたので、それを生き生きとさせましょう! この章では、table view controllerを動作させるために実装する必要があるさまざまな関数に焦点を当てます。
前に説明したように、これらの関数は、table view controllerデリゲートまたはtable view controllerデータソースのいずれかに属します。 これらのプロトコルはどちらも委任を使用してテーブルビューをカスタマイズします。
UITableViewDataSource
の最も重要な機能は次のとおりです:
numberOfSections(in:)
tableView(_:numberOfRowsInSection:)
tableView(_:cellForRowAt:)
UITableViewDelegate
に関連するその他の関数は次のとおりです:
tableView(_:didSelectRowAt:)
tableView(_:willDisplay:for:)
UitableviewdelegateおよびUITableViewDataSourceのApple Developer Documentationには、さらに多くの関数があります。
連絡先データの追加
まず、テーブルビューコントローラの連絡先情報データを追加します。 次のプロパティをContactsTableViewController
クラスに追加します:
let contacts:] = , , , , , , , , , , , , , , , , ]
それは我々がすべて持っているしたいと思いますrolodexですよね? ここでは、それがどのように動作するかです:
-
let contacts
はcontacts
という名前の定数を宣言します。 それをクラスにプロパティとして追加したので、すべてのクラスインスタンスはクラスのコード全体でこの定数にアクセスできます。 -
contacts
の型は]
で、これは文字列の配列の配列です。 基本的には、項目が文字列の配列である配列を作成しています。 (変数名とその型はコロンで区切られます:
) -
=
コードは配列リテラルをcontacts
に割り当て、数人の億万長者の名前と電話番号を記入します。
後の時点で、配列内の項目数をcontacts.count
で使用できます。 また、添字構文を使用して、contacts
とcontacts
を使用して個々の名前と電話番号を取得できます。
テーブルビューセルクラスの登録
テーブルビューコントローラでセルを使用する前に、それらをテーブルビューに登録する必要があります。 これは次の2つの方法で行うことができます。:
- テーブルビューセルクラスと識別子を提供することにより
- テーブルビューセルXIBと識別子を提供することにより
カスタムテーブルビューセルを使用しているときは、そのためにXIBを登録することが最も可能性が高い。 デフォルトのテーブルビューセル、またはその他のプログラムセルを使用している場合は、クラスを登録します。 今のところ、クラスを使用します!
次のコードをviewDidLoad()
関数に追加します:
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
必ずsuper.viewDidLoad()
行の下に追加してください。 ご存知のように、viewDidLoad()
関数はview controllerのライフサイクルの一部であり、UIViewController
クラスに属しています。
view controllerのライフサイクルでこのイベントに応答するようにviewDidLoad()
関数をオーバーライドしているため、ビューがロードされた後にビューを設定できます。 私たちの場合、テーブルビューセルを登録するために関数を使用しています。
テーブルビューセルを登録するときは、識別子も指定する必要があります。 これは、tableView(_:cellForRowAt:)
でセルをデキューするときに、セルのクラスを後で使用できる名前に関連付けるためです。
あなたはまだ私と一緒にいますか? 先に進もう!
“numberOfSections(in:)”の実装
最初に実装するデリゲート関数はnumberOfSections(in:)
です。
テーブルビューは複数のセクションまたはグループを持つことができます。 すべてのグループには、縦列のセルの上に浮かぶヘッダーがあります。 連絡先アプリでは、連絡先をアルファベット順にグループ化できます。 これは実際には、連絡先がA-Zグループ化されているiPhoneの連絡先アプリで行われます。
私たちが構築しているアプリには、一つのセクションしかありません。 クラスに次の関数を追加します:
override func numberOfSections(in tableView: UITableView) -> Int{ return 1}
簡単、右か。 この関数は、呼び出されたときに1
を返します。
“tableView(_:numberOfRowsInSection:)”を実装しています
同様の関数はtableView(_:numberOfRowsInSection:)
です。 セクションの数を指定する代わりに、セクション内の行の数を指定します。 テーブルビューではセルが垂直リストに表示されるため、すべてのセルはテーブルビューの行に対応します。
私たちが構築しているアプリには1つのセクションがあり、その1つのセクションにはcontacts
配列のアイテムの数に等しいアイテムの数があります。 だから、それはcontacts.count
です!
クラスに次の関数を追加します:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return contacts.count}
それがどのように動作するか見てください? 単純にcontacts.count
を返します。 別の名前と電話番号をcontacts
に追加すると、テーブルビューにもうまく表示されます。
行とセクションの理解
私たちの連絡先アプリは一次元であり、名前と電話番号のリストを一つだけ表示し、グループを使用しません。 しかし、グループ化されたテーブルビューがある場合はどうなりますか?
ほとんどの場合、contacts
配列のようなデータソースも多次元になります。 最初のレベルではグループを整理し、2番目のレベルでは個々のアイテムをグループの「下」に整理します。
- Countries - A - Afghanistan - Albania - ... - B - Bahamas - Bahrain - ... - C - Cambodia - Cameroon - ...
グループの数はcountries.count
に等しく、単一のグループ内の国の数はcountries.count
に等しくなります。x
はセクションインデックスです。 そのセクション索引は、tableView(_:numberOfRowsInSection:)
のパラメータとして提供されます。
これら二つの関数がtableView
というパラメータを持っていることに気付きましたか? これはオブジェクト指向プログラミングの原則の一部です。 技術的には、テーブルビューデータソースとデリゲートを使用して、複数のテーブルビューをカスタマ 作業しているテーブルビューを識別するには、tableView
を使用します。
電話番号を名前で表示できる連絡先アプリ、または会社別に整理された電話番号を表示できる連絡先アプリがあるとします。 たとえば、テーブルビューコントローラを再利用するなど、複数の方法で実装できます。 または、連絡先アプリのレイアウトを再利用して、レストラン、会場、Skypeのユーザー名などの同様の情報を表示する場合はどうすればよいですか? それがOOPでのコードの再利用の出番です!テーブルビューコントローラにセルを提供する
私たちはそこに着いています! テーブルビューコントローラの最も重要な機能tableView(_:cellForRowAt:)
に移りましょう。
詳細に入る前に関数を実装しますが、それについて理解する必要があることがいくつかあります:
- インデックスパスとは
- セルを再使用する方法
最初に、次の関数をContactsTableViewController
クラスに追加します:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{}
ここでは、それがどのように動作するかです:
- この関数は、
UITableViewController
からのスーパークラスの実装をオーバーライドします。 今ではそれがどのように機能するか知っていますよね? 私たちはデフォルトの実装をオーバーライドし、私たち自身のものに置き換えています。 これは、UITableViewController
がすでにテーブルビューのデリゲートとデータソースを実装しているためです。 - 前と同様に、関数には、この関数が呼び出されるテーブルビューを識別するために使用できる1つのパラメータ
tableView
があります。 - 別のパラメータは
indexPath
で、引数ラベルはcellForRowAt
です。 インデックスパスは、セルのrow
およびsection
インデックスを識別します。 それについては後で詳しく説明します。 - 関数の戻り値の型は
UITableViewCell
です。 こんにちは、面白かったです。 この関数は、テーブルビューのセルを提供する必要があるたびに、テーブルビューコントローラによって呼び出されます!
このアプリで連絡先をスクロールすると、画面にセルを表示する必要があるたびに、関数tableView(_:cellForRowAt:)
が呼び出されます。 毎回! すぐに証明する
次は、関数本体を記述しましょう。 関数内に次のコードを追加します:
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")cell.textLabel?.text = contactsreturn cell
ここで何が起こるかです:
- まず、識別子を持つセルをデキューします。 これは、セルを登録するときに以前に使用したのとまったく同じ識別子です。 そうすれば、テーブルビューはどのタイプのセルを必要とするかを知ることができます。 デキューされたセルは
cell
定数に割り当てられます。 これで、作業するテーブルビューセルができました。 後でdequeuingの詳細。 - 次に、コンソールにいくつかの情報を出力します。 これは、アプリの実行時に、この関数がいつ呼び出されるかを確認できるようにするためです。
- 次に、このテーブルビューセルのテキストラベルに連絡先の名前を割り当てます。
contacts
には、indexPath.row
を使用して取得する連絡先の名前の値が含まれています。UITableViewCell
のすべてのインスタンスにはUILabel
のプロパティtextLabel
があり、そのタイプのすべてのラベルにはプロパティtext
があります。 これを使用して、ラベルにテキストを設定します。
心配しないで、これらの各ことをより詳細に説明します。 まず、アプリを実行できるかどうかを確認します。 連絡先の名前は表示されますか? コンソールにデバッグ出力が表示されますか? アプリをスクロールしてみてください!
“tableView(_:cellForRowAt:)”が呼び出されるのはいつですか?
連絡先アプリを実行し、上下にスクロールして遊んだ場合、スクロールするたびにデバッグ出力がコンソールに表示されることに気づくことはできません。
以前に画面に表示されていなかったセルが表示されるたびに、関数tableView(_:cellForRowAt:)
が呼び出され、コンソールに新しい行が表示されます。
では、tableView(_:cellForRowAt:)
はいつ呼び出されますか? テーブルビューセルを画面に表示する必要があるたびに!
テーブルビューコントローラは、セルが必要であると判断したため、tableView(_:cellForRowAt:)
を呼び出します。 この関数の実装では、セルをデキューして変更し、テーブルビューコントローラに返します。 テーブルビューコントローラとUIKitフレームワークは、画面上にグラフィカルにレンダリングします。
インデックスパスとは何ですか?
テーブルビューコントローラがtableView(_:cellForRowAt:)
のセルを必要とするたびに、関数の引数としてインデックスパスを提供します。 関数本体内では、パラメータindexPath
を使用して、テーブルビューコントローラが必要とするセルを正確に知ることができます。
インデックスパスは、アドレス、またはグリッド内の座標のようなものです。 典型的なグラフはX軸とY軸を持っているので、そのグラフの座標を0, 1
や42, 3
のようにx, y
として表現することができます。 同様に、スプレッドシートにはインデックスを持つ行と列があります。
テーブルビューはセクションと行を使用します。 前に説明したように、セクションを使用してセルをグループ化できます。 私たちのアプリには1つのセクションしかなく、contacts.count
行があります。 テーブルビューの行は、上から下に実行されます。
は、テーブルビューのセクションと行がスプレッドシートの列と行であることを示しています。 インデックスパスは、行とセクションを使用して、テーブルビュー内の場所を定義します。
行とセクションはインデックスと呼ばれる数字で表されます。 これらのインデックスはゼロから始まるため、最初の行とセクションのインデックス番号は0
になります。
前のスクリーンショットを振り返ると、それははるかに理にかなっています。 最初のセルにはインデックスパス0, 0
、2番目のセル0, 1
があり、インデックスパス0, 11
を持つ最後の可視セルまで続きます。
テーブルビューの再利用メカニズム
テーブルビューについて最も注目すべきは、セルの再利用のメカニズムです。 それは実際には、非常に簡単です。
- テーブルビューコントローラが画面にセルを表示する必要があるたびに、前に説明したように、関数
tableView(_:cellForRowAt:)
が呼び出されます。 - その関数が呼び出されるたびに新しいテーブルビューセルを作成する代わりに、キューから以前に作成されたセルを選択します。
- セルは空の状態にリセットされ、その外観がクリアされ、セルは
tableView(_:cellForRowAt:)
で再びカスタマイズされます。 - セルが画面外にスクロールされるたびに、それは破壊されません。 キューに追加され、再利用されるのを待っています。
それはかなり賢いですよね? セルを作成および削除する代わりに、セルを再利用するだけです。 でも…なぜ?
セルを再利用するのははるかに少ないメモリ集約型です。 テーブルビューコントローラは、セルの作成と削除時に常にメモリに書き込みます。 メモリの管理もより集中的になります。 セルが再利用されると、メモリがより効率的に使用され、必要なメモリ操作が少なくなります。
また、ittは、セルの作成と削除に比べて、再利用に関わる操作が少ないため、セルを作成および削除するのではなく、セルを再利用するためのCPU集約
テーブルビューをすばやくスクロールすると、新しいセルが表示されず、同じセルが何度も何度も表示され、新しい情報が表示されます。
セルの再利用に関連するコードは次のとおりです:
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)
関数dequeueReusableCell(withIdentifier:)
は、セルのデキューを試みます。 キューにセルがない場合は、セルが作成されます。 識別子は、すべてのタイプのセルを独自のキューに保持し、新しいセルを作成するために正しいクラスが使用されることを確認するために使用され
iOSアプリの構築方法を学ぶ
iOS14とSwift5を使い始める
iOS開発コースにサインアップし、Swift5とXcode12で優れたiOS14アプリを構築する方法を学びます。
ユーザー操作への応答
テーブルビューコントローラには欠けていることがあります。 しかし、その前に、table view controllerで連絡先の電話番号も確認できるようにしましょう。
デフォルトのUITableViewCell
クラスには、UITableViewCellStyle
列挙で表現されているように、4つの異なる型があります。 次のいずれかを選択できます:
-
.default
– 黒のテキストの一行を持つシンプルなビュー -
.value1
– 左側に黒いテキストの一行、右側に小さな青いラベルを持つシンプルなビュー(設定アプリで使用されます) -
.value2
– 右側に黒いテキストの一行、左側に小さな青いラベル(連絡先アプリで使用される)を持つシンプルなビュー) -
.subtitle
– 1行の黒いテキストとその下の灰色のテキストの小さな行を持つ単純なビュー
ほとんどの開発者は、最近カスタムテーブルビューのセルを使用してい しかし、彼らはそこにいる!
tableView(_:cellForRowAt:)
のコードを少し調整しなければなりません。 関数の最初の行を次のコードに置き換えます:
var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier")if cell == nil{ cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier")}
よく見ると、dequeueReusableCell(...)
呼び出しのfor: indexPath
部分が削除されていることがわかります。 代わりに、その関数はoptionalを返すようになりました。 セルをキューに入れることができない場合、関数はnil
を返します。
その後、セルがnil
の場合、自分自身でジャンプしてセルを作成します。 あなたはコードの2番目の部分でそれを見ます。 条件付きif
ステートメントを使用して、cell
がnil
と等しいかどうかを確認し、それが真の場合は、UITableViewCell(style:reuseIdentifier:)
初期化子を使用してセルを作成します。
その初期化子は、2つの引数、セルスタイル.subtitle
、および前に使用した識別子を取得します。
この時点で、cell
は現在オプションであるため、問題があります! その型はUITableViewCell?
ですが、関数の戻り値の型は、オプションではない型UITableViewCell
のインスタンスを返すことを要求します。
幸いなことに、これは安全にforce unwrappingを使用してオプションの値をアンラップすることができるインスタンスの一つです。 私たちのコードが書かれている方法のために、cell
が条件付きを超えてnil
になることは不可能です。 if
文の後にcell
がnil
ではないことを保証することができます。
cell
に対して強制アンラップを使用するように関数を更新してください。 また、セルのサブタイトルを設定するには、cell!.textLabel ...
の下に次のコード行を追加して、連絡先の電話番号を表示します。
cell!.detailTextLabel?.text = contacts
関数全体は次のようになります:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") if cell == nil { cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier") } print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)") cell!.textLabel?.text = contacts cell!.detailTextLabel?.text = contacts return cell!}
最後に、viewDidLoad()
から次の行を削除してください。 テーブルビューが間違ったタイプのセルを初期化するのを防ぎます。
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
マイティファイン! Command+RまたはPlayボタンを使用してアプリを実行し、動作するかどうかを確認します。 名前と電話番号が表示されますか? よし!
次に、pièce-de-résistanceのために、そのユーザー対話機能を追加しましょう。 Table view controllerの複雑さを学んだので、この次の関数がどのように機能するかはすでに知っていると思います。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ if let url = URL(string: "tel://" + contacts) { UIApplication.shared.open(url) }}
ここでも、tableView(_:didSelectRowAt:)
関数のデフォルトの実装をオーバーライドしています。 この関数は、ユーザーがテーブルビューのセルをタップしたときに呼び出され、UITableViewDelegate
プロトコルに属します。 他の関数と同様に、タップされたセルのインデックスパスが提供されます。
関数本体では、電話番号からtel://
URLを作成するだけです。 次に、アプリにそのURLを開くように指示し、iOSにこの番号への通話を開始するように効果的に指示します。 そのコードは、例示目的のためにのみ存在します。 これはiPhone Simulatorでは機能せず、アプリの数字は偽物であることに注意してください。 (それでも、実際の連絡先アプリを作成している場合は、このコードを使用します!)
正常に動作するかどうかを確認したい場合は、次のコードを関数に追加することができます。
print("\(#function) --- Calling: \(contacts)")
テーブルビューのセルをタップするとデバッグメッセージが出力されます。
さらに読む
そして、それはそれにあるすべてです! それはかなりの旅行でしたが、今ではテーブルビューコントローラがどのように機能するかを知っています。