今回も UIKit
を用いて iOS 開発を行うときのチップス集的な技術ブログ「同じような処理だけどこっちの方がいいよってやつ」を眺めていきます。その中の UITableView
のところから今日は続けて見ていきますね。よろしくお願いします。
—————————————————————————————————————————————— 熊谷さんのやさしい Swift 勉強会 #289
00:00 開始 00:23 今日は UITableView についての話 00:35 UITableView のイニシャライザー 02:52 CGRect.null とは 04:06 無効な値を示す表現 06:21 CGRect.infinite という表現 08:48 UITableView ではなく UICollectionView を使う 13:35 考えるための情報量 15:43 UICollectionView ならではの表現力に期待 16:35 CGRect.zero を、いったいどう書き換える? 19:27 CGRect.null で空の View を表現できる⋯? 21:02 CGRect.null に感じる恐怖心 22:44 UIView(frame: .null) を addSubView して大丈夫? 25:23 なんのために CGRect.null が存在しているのか 26:43 クロージングと次回の展望 ——————————————————————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #289
はい、では始めていきます。今回は株式会社ゆめみの勉強会です。テーマは前回に引き続き Swift についてです。今回はのってさんのブログを参考にしながら進めます。前回は数字の変換について学びましたので、今回は UITableView
について見ていきます。
UITableView
ですが、通常はストーリーボードでインスタンス化することが多く、イニシャライザーからインスタンス化することはあまりありません。しかし、イニシャライザーからインスタンス化する方法も気になるところです。
まず UITableView
のイニシャライザーについて見てみましょう。プレイグラウンドで試してみますね。ここでは UIKit
をインポートします。UIKit
は現在でも使用されているフレームワークです。
import UIKit
次に、UITableView
のイニシャライザーを確認します。デフォルトのイニシャライザーは、NSObject
を継承しているため、以下のようになります。
let tableView = UITableView()
Objective-C のイニシャライザーは隠蔽されていることが多いですが、このケースでも特に問題はありません。コメントを見てみると、Objective-C の医療(メソッド)に触れてはいませんが、アーカイブ機能を提供する init(coder:)
というイニシャライザーもあります。これは NSCoding
プロトコルに準拠しているため、アーカイブ機能が必要な場合に使用されます。
required init?(coder: NSCoder) {
super.init(coder: coder)
// カスタムな初期化コードをここに書きます
}
通常の開発では、この init(coder:)
を利用する機会は少ないと思います。これからは SwiftUI の導入も進んでおり、さらに使用頻度が減るかもしれません。
今回は UITableView
のイニシャライザーに焦点を当てました。次回は別の UI コンポーネントや Swift の言語仕様についても掘り下げていきます。それでは、次の内容に移ります。 UIやその辺の関連で特定のタイプを指定する際に、Objective-Cのランタイムでの設定方法は置いておきましょう。次に、Swiftでの特定のタイプの指定について説明します。
Swiftでは、特定のプロトコルや型を指定するときにtypealias
を使います。例えば、あるプロトコルに準拠することを明示的に示す際に使用します。
例えば、以下のようにtypealias
を使って特定の型を指定できます。
protocol SomeProtocol {
func doSomething()
}
typealias CustomType = SomeProtocol
このようにすることで、CustomType
はSomeProtocol
のエイリアスとして機能します。
他にもジェネリクスを使用することで、より柔軟に特定の型を扱うことができます。以下はジェネリクスの例です。
func genericFunction<T: SomeProtocol>(_ item: T) {
item.doSomething()
}
この関数は、SomeProtocol
に準拠する任意の型T
を引数として受け取ります。
こうしたSwiftの言語仕様を理解することが重要です。特定の用途に応じて適切な方法を選択することで、柔軟かつ頑健なコードを書くことができます。
まとめ
- Swiftでは
typealias
を使って特定の型を指定できます。 - ジェネリクスを用いることで、異なる型でも共通の処理を行う関数を作成できます。
- これにより、コードの再利用性や柔軟性が向上します。 原点(ゼロ)でゼロかけるゼロの命令を返す...すごいですね。これだけでまだまだ続きそうですけど、具体的に
CGRect.zero
をどのように操作して、どのような結果を求めているのでしょうかという質問がありました。
そうですよね。いくつかの解釈に対応する方法があります。新しいCGRect
のインスタンスを生成する初期化方法を使って生成する案が用意されています。また、CGRect.zero
の一部のプロパティを変更する方法もあります。ですが、それはあまり推奨されません。CGRect.zero
は広く使用されるAPIであり、それを変更すると予期しない副作用や互換性の問題が生じる可能性があります。
一般的に、こう動くはずだという共通認識を持っている場合、それから外れるような行動を避けるべきです。この点はAPIデザインガイドラインにもありますね。具体的な方法について、どういうイメージを持っているかによって、少し違和感を感じるようなことを言っていましたね。
UIViewフレームにヌルを使うというアイデアも出ましたが、ヌルにするとエンプティビューになるのかもしれません。ゼロがゼロに存在するという完全なスクリプトのゼロで存在するみたいな状態を決めたい場合など、存在しない初期状態を指したいことが大半です。そのとき、ヌルを使うのは適切でないかもしれません。
ここで、実際にUIViewフレームにヌルを使用した経験があるかどうかが話題になりましたが、それを使う設計ではない感じもしました。サブビューを持たないビューであれば、存在しないという形でゼロとして扱うのが良いかもしれませんが、ランタイムエラーが発生する可能性もありますね。
とりあえずコードとして試してみましょうか。例えば以下のように試せます。
let redView = UIView(frame: CGRect.zero)
この状態で、ビューをサブビューとして追加するとどうなるのか確認してみます。時間があまりないので、iOSシミュレーターが使える場合、それを使ってみると良いかもしれません。アプリを作ってビューコントローラーからサブビューとして追加してみて、その挙動を確認します。
具体的な結果としては、サイトがゼロなので表示されることはなくどこにも見えないでしょう。しかし、サブビューに追加しているので、メッセージは受け取ることができます。
今回は時間切れですが、次回はこの続きを見るか、または他の面白そうな研究課題に取り組みたいと思います。今日はこれで終わりにします。お疲れ様でした。ありがとうございました。