- 投稿日:2020-11-26T23:45:11+09:00
classとstructについて【Swift】
はじめに
class
とstruct
の違いについて理解が薄かったので、備忘録としての投稿させていただきます。
class
とstruct
の定義
struct
の場合struct Human { let name: String let age: Int }
class
の場合struct Human { let name: String let age: Int // プロパティを初期化しないと下記メッセージのように怒られます。 // Class 'Human' has no initializers init(name: String, age: Int) { self.name = name self.age = age } }
class
とstruct
の使い分け1.
class
とstruct
の大きな違い
struct
は値型(継承できない、内部を直接書き換えることは不可)
class
は参照型(継承できる、内部の書き換えるが可能)2.
struct
を使うパターン
- 小さくて単純なデータをカプセル化をしたい場合
- 参照渡しより値渡し(コピー)が良い場合
- 継承が必要ない場合
3.
struct
を使わない方が良いパターン
- データが大きい
- プロパティが多い
理由としては、以下の2つ
- 構造体は変数にセットする度にコピーされるため、データが大きいと処理時間が遅くなる
- 構造体はスタック領域に確保されるため、データが大きいと溢れる可能性が高くなる なので、APIやDBの取得データなどは構造体ではなく、クラスで作成したほうがよい。
4. 比較詳細
class struct プロトコル実装 ○ ○ プロパティ(格納型) ○ ○ プロパティ(算出型) ○ ○ タイププロパティ(格納型) ✕ ○ タイププロパティ(算出型) ○ ○ メソッド ○ ○ タイプメソッド ○ ○ 5. 補足
タイププロパティ
すべてのインスタンスが利用できる(C の static 定数のような)定数プロパティ、あるいは特定の型のすべてのインスタンスにグローバルな値を保管する(C の static 変数のような)変数プロパティのように、その型のすべてのインスタンスに共通の値を定義するのに役に立つ。
タイプメソッド
型自体で呼び出せるメソッド。
- 投稿日:2020-11-26T22:07:24+09:00
PRPreviewViewControllerの再生が一回しかできない
ReplayKitでの画面収録をプレビューするPRPreviewView。
再生ボタンが最初の1回しか表示されない、と思ったら、モーダル表示した時に、再生・停止ボタンとActivityボタンが画面の下に切れてしまっていた。
フルスクリーンでモーダル表示すると、全部表示されます。let sharedRecorder = RPScreenRecorder.shared() .......... sharedRecorder.stopRecording(handler: { (previewViewController, error) in previewViewController?.previewControllerDelegate = self previewViewController?.modalPresentationStyle = .overFullScreen // このラインをプラス self.present(previewViewController!, animated: true) { } })?
お仕事のご相談こちらまで
rockyshikoku@gmail.comCore MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。
- 投稿日:2020-11-26T21:40:30+09:00
【Swift】UISearchBarの検索テキストの色を変更する
- 投稿日:2020-11-26T21:11:22+09:00
iOSアプリ用スクリーンショットサイズ一覧(縦, 横)
デバイスのサイズ 縦サイズ 横サイズ 6.5 インチ(iPhone 12 Pro Max, iPhone 12 Pro, iPhone 12, iPhone 11 Pro Max, iPhone 11, iPhone XS Max, iPhone XR) 1284 x 2778 ピクセル 2778 x 1284 ピクセル 5.8 インチ (iPhone 12 mini, iPhone 11 Pro、iPhone XS、iPhone X) 1125 x 2436 ピクセル 2436 x 1125 ピクセル 5.5 インチ (iPhone 8 Plus、iPhone 7 Plus、iPhone 6s Plus) 1242 x 2208 ピクセル 2208 x 1242 ピクセル 4.7 インチ (iPhone SE (第 2 世代)、iPhone 8、iPhone 7、iPhone 6s、iPhone 6) 750 x 1334 ピクセル 1334 x 750 ピクセル 4 インチ (iPhone SE (第 1 世代)) 640 x 1096 ピクセル(縦向きステータスバーなし) 640 x 1136 ピクセル(縦向きステータスバーあり) 1136 x 600 ピクセル(横向きステータスバーなし)1136 x 640 ピクセル(横向きステータスバーあり) 12.9 インチ (iPad Pro (第 4 世代、第 3 世代)) 2048 x 2732 ピクセル 2732 x 2048 ピクセル 12.9 インチ (第 2 世代 iPad Pro) 2048 x 2732 ピクセル 2732 x 2048 ピクセル 11 インチ (iPad Pro、第 4 世代 iPad Air) 1668 x 2388 ピクセル 2388 x 1668 ピクセル 10.5 インチ (iPad (第 8 世代、第 7 世代)、iPad Pro、iPad Air) 1668 x 2224 ピクセル 2224 x 1668 ピクセル 9.7 インチ(iPad、iPad mini) 1536 x 2008 ピクセル(縦向きステータスバーなし) 1536 x 2048 ピクセル(縦向きステータスバーあり) 2048 x 1496 ピクセル(横向きステータスバーなし) 2048 x 1536 ピクセル(横向きステータスバーあり) 参考
- 投稿日:2020-11-26T20:41:29+09:00
【第5回】初心者二人で0から麻雀アプリ開発
改版履歴
2020/11/26 投稿
第5回会議(2020年11月23日)
今回はいよいよ実装!……に入るための勉強会を実施しました。
これまでは個々に情報収集、学習を行なってきましたが、今回以降は足並みを揃える+毎週の学習時間確保を目的として、定例会議の場で学習した内容の共有をして行く予定です。議題
- プロジェクトの立ち上げ
- ヘッダー・フッター表示
- テーブル表示
形式
今回は最初の勉強会でしたので、どんな形式で、どのように進行したかを残しておこうと思います。
使用したツール
- google meet
- google スライド
- Xcode
事前準備
- お互いに学習テーマを決める
- 一週間の間にテーマの調査・実装を行い、スライドにまとめる
当日
- 順番にスライド発表
- 質疑応答
- 課題点整理
- 次回のテーマ決定
勉強会
結論から言うと、実装についてはプロジェクト作成までしか実現出来ませんでした。
コンパイルエラーの解決は次週に持ち越しです……今記事では、スライド発表後の課題点整理で挙がった内容を列挙します。
問題① 使用しているバージョンに対応した学習ソースがない
現在、本プロジェクトで使用しているバージョンは以下の通りです
swift: 5.3
Xcode: 12.2特に、Xcodeは最近大きなアップデートがあり、開発画面のレイアウトが大きく変わってしまったようです。
過去の記事に書いてある内容を現在のバージョンで実現する操作がどれに当たるのか、という作業に難航しています。問題② ライブラリに対する知識不足
第3回にて、iosSDKを使用すると漠然と決めましたが、上記のテーマを実現する方法は複数あることがわかってきました。
大きく、UIKit,swiftUI,オープンソースのライブラリを使っての実装が考えられますが、3者をあまり区別なく調査している状況です。そのため、実装に対する共通認識を持ちづらく、お互いの調査結果についてレビューしづらいという弊害がでています。
共同開発をする上でも、基本の画面や、共通部に使用するライブラリは揃えていく必要がありそうです。
エラーの原因がわからない
これは特にswiftUIでの実装にいえるのですが、コンパイルエラーの箇所やエラーメッセージについて、英文でわかりづらい、翻訳を駆使しても原因の特定にじかんがかかってしまう。
また、エラーの直接原因が、エラーが出ている個所でない場合があり、特定できない。などです。
根本的な基礎知識が不足しているのが原因ではありますが、現在の学習方法では上記の問題を解決しづらいのではないかと考えています。
詰まった場合の解決策をまとめておく等の対応が必要かもしれません。
おわりに
今回は一回目の勉強会についてお送りしました。
本来は、勉強会の成果を本記事でアウトプットしていくのがよいとは思っていますが、一記事になるほどのネタがありませんでした……次回以降、投稿内容等も含めて、課題を消化していきたいと思います。
(会議の全体概要を投稿していくのではなく、勉強会の一部分をピックアップしてまとめるというスタイルでもいいかもしれません。ネタがあればですが。)
- 投稿日:2020-11-26T19:36:36+09:00
@Published を監視する
struct Content: Hashable { let name: String } extension Content: Identifiable { var id: Content { self } } class ContentViewModel: ObservableObject { @Published var contents: [Content] = [.init(name: "piyo")] }上記のようなViewModelを実装した際に
contents
の更新を監視したい場合がある解決策
viewModel.$contents .sink { contents in print(contents) }もしくは
viewModel.objectWillChange .sink { print("willChange") }これで値を購読することができる
注意するべきポイントとして、どちらも値更新前に呼ばれるのでsinkが呼ばれたタイミングでは値は更新されていない。
プロパティを直接購読する場合は更新後の値が取れるが、
objectWillChangeを購読する場合はObservableObjectに生えているプロパティそれぞれの更新タイミングを取得することができるが更新後の値は取得できない。余談
ちなみに、ViewのinitializerなどでViewModelにあるPublishedObjectの更新前の値を参照したい場合に直接クロージャーで扱おうとすると
Escaping closure captures mutating 'self' parameter
と出てしまうので、値をコピーする必要がある。
コピーをするだけなのでクロージャー内で値を書き換えてもViewの保持するViewModelには何も影響は出ない。viewModel.$contents .sink { [previousContents = viewModel.contents] _ in print(previousContents) }typealias DisposeBag = Set<AnyCancellable> struct ContentView: View { @ObservedObject var viewModel = ContentViewModel() private var disposeBag = DisposeBag() var body: some View { NavigationView { List { ForEach(viewModel.contents) { content in NavigationLink( destination: Text(content.name), label: { Text(content.name) }) } } } } init() { viewModel.$contents .sink { [previousContents = viewModel.contents] contents in print(contents) print(previousContents) } .store(in: &disposeBag) } }
- 投稿日:2020-11-26T08:09:59+09:00
【Swift】Stringの改行する方法
SwiftでのStringの改行の方法です。
動作環境 バージョン Xcode 12.1 Swift 5 改行方法その① 改行文字 \n を使う
let newLineCharacter = "newLine\nCharacter" print(newLineCharacter)出力結果
newLine
Characterバックスラッシュ " \ " の打ち方
option
+¥
改行方法その② 3つの二重引用符 """ を使う
let newLineString = """ new Line String """ print(newLineString)""" 3つの二重引用符で挟むと、改行がそのまま出力結果に反映されます。
出力結果
new
Line
String文字列に"二重引用符"を含める
3つの二重引用符で挟む場合は、文字列に"二重引用符"を含むことができます。
let newLineString = """ new "Line" String """ print(newLineString)出力結果
new
"Line"
String間違った書き方
let mistakeString = """mistake String """複数行文字列リテラルは改行から必ず開始してください。
ということで、開始と終了する時には改行が必要です。
参考
[Swift]改行の仕方
How to create multi-line string literals
それでは、Swiftでの改行ライフをお楽しみください!
- 投稿日:2020-11-26T01:26:28+09:00
[iOS]モーダルを音速で閉じる
この記事は「[iOS]音速でモーダルを実装する」の続きです。
モーダル開いたらモーダル閉じたいよなぁ?という記事です。バージョン
Swift 5.3
Xcode 12.1モーダルを閉じる
モーダルを閉じるにはUIViewControllerのインスタンスメソッドであるdismissを使います。
実装
ファイルの追加
まず、モーダル用のViewControllerを追加します。
New File...から
Cocoa Touch Classを選択してNextをクリック
今回はModalViewControllerという名前にしてファイルを作成します。ファイルとビューの関連付け
閉じる用のボタンを配置
モーダルを閉じる関数を書く
モーダルを閉じる関数を書きます。
ModalViewController.swiftimport UIKit class ModalViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func closeModal() { self.dismiss(animated: true, completion: nil) } }ボタンと関数を関連付ける
ボタンと関数を関連付けます。
完成
参考文献