20201126のSwiftに関する記事は8件です。

classとstructについて【Swift】

はじめに

classstructの違いについて理解が薄かったので、備忘録としての投稿させていただきます。

classstructの定義

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
    }
}

classstructの使い分け

1. classstructの大きな違い

  • structは値型(継承できない、内部を直接書き換えることは不可)
  • classは参照型(継承できる、内部の書き換えるが可能)

2. structを使うパターン

  • 小さくて単純なデータをカプセル化をしたい場合
  • 参照渡しより値渡し(コピー)が良い場合
  • 継承が必要ない場合

3. structを使わない方が良いパターン

  • データが大きい
  • プロパティが多い

理由としては、以下の2つ

  • 構造体は変数にセットする度にコピーされるため、データが大きいと処理時間が遅くなる
  • 構造体はスタック領域に確保されるため、データが大きいと溢れる可能性が高くなる なので、APIやDBの取得データなどは構造体ではなく、クラスで作成したほうがよい。

4. 比較詳細

class struct
プロトコル実装  ○   ○ 
プロパティ(格納型)  ○   ○ 
プロパティ(算出型)  ○   ○ 
タイププロパティ(格納型)  ✕   ○ 
タイププロパティ(算出型)  ○   ○ 
メソッド  ○   ○ 
タイプメソッド  ○   ○ 

5. 補足

タイププロパティ

すべてのインスタンスが利用できる(C の static 定数のような)定数プロパティ、あるいは特定の型のすべてのインスタンスにグローバルな値を保管する(C の static 変数のような)変数プロパティのように、その型のすべてのインスタンスに共通の値を定義するのに役に立つ。

タイプメソッド

型自体で呼び出せるメソッド。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

Twitter
Medium

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】UISearchBarの検索テキストの色を変更する

searchBar.textColorみたいな感じでいけると思っていましたが、そう簡単にはいきませんでした。

動作環境 バージョン
Xcode 12.1
Swift 5

SearchBarの検索テキストの色を変更するコード

//例として検索テキストの色を赤色に変更
searchBar.searchTextField.textColor = .red

まとめ

UISearchBarのプロパティのsearchTextFieldのTextColorを変更すると検索テキストの色が変更できます。

参考

UISearchBarの検索テキストの色を変更するにはどうすればよいですか?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 ピクセル(横向きステータスバーあり)

参考

https://help.apple.com/app-store-connect/#/devd274dd925

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【第5回】初心者二人で0から麻雀アプリ開発

第4回はこちら

改版履歴

2020/11/26 投稿

第5回会議(2020年11月23日)

今回はいよいよ実装!……に入るための勉強会を実施しました。
これまでは個々に情報収集、学習を行なってきましたが、今回以降は足並みを揃える+毎週の学習時間確保を目的として、定例会議の場で学習した内容の共有をして行く予定です。

議題

  • プロジェクトの立ち上げ
  • ヘッダー・フッター表示
  • テーブル表示

形式

今回は最初の勉強会でしたので、どんな形式で、どのように進行したかを残しておこうと思います。

使用したツール

  • google meet
  • google スライド
  • Xcode

事前準備

  1. お互いに学習テーマを決める
  2. 一週間の間にテーマの調査・実装を行い、スライドにまとめる

当日

  1. 順番にスライド発表
  2. 質疑応答
  3. 課題点整理
  4. 次回のテーマ決定

勉強会

結論から言うと、実装についてはプロジェクト作成までしか実現出来ませんでした。
コンパイルエラーの解決は次週に持ち越しです……

今記事では、スライド発表後の課題点整理で挙がった内容を列挙します。

問題① 使用しているバージョンに対応した学習ソースがない

現在、本プロジェクトで使用しているバージョンは以下の通りです
swift: 5.3
Xcode: 12.2

特に、Xcodeは最近大きなアップデートがあり、開発画面のレイアウトが大きく変わってしまったようです。
過去の記事に書いてある内容を現在のバージョンで実現する操作がどれに当たるのか、という作業に難航しています。

問題② ライブラリに対する知識不足

第3回にて、iosSDKを使用すると漠然と決めましたが、上記のテーマを実現する方法は複数あることがわかってきました。
大きく、UIKit,swiftUI,オープンソースのライブラリを使っての実装が考えられますが、3者をあまり区別なく調査している状況です。

そのため、実装に対する共通認識を持ちづらく、お互いの調査結果についてレビューしづらいという弊害がでています。

共同開発をする上でも、基本の画面や、共通部に使用するライブラリは揃えていく必要がありそうです。

エラーの原因がわからない

これは特にswiftUIでの実装にいえるのですが、コンパイルエラーの箇所やエラーメッセージについて、英文でわかりづらい、翻訳を駆使しても原因の特定にじかんがかかってしまう。
また、エラーの直接原因が、エラーが出ている個所でない場合があり、特定できない。

などです。

根本的な基礎知識が不足しているのが原因ではありますが、現在の学習方法では上記の問題を解決しづらいのではないかと考えています。

詰まった場合の解決策をまとめておく等の対応が必要かもしれません。

おわりに

今回は一回目の勉強会についてお送りしました。
本来は、勉強会の成果を本記事でアウトプットしていくのがよいとは思っていますが、一記事になるほどのネタがありませんでした……

次回以降、投稿内容等も含めて、課題を消化していきたいと思います。
(会議の全体概要を投稿していくのではなく、勉強会の一部分をピックアップしてまとめるというスタイルでもいいかもしれません。ネタがあればですが。)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

@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)
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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
"""

この記述だと、Xcodeに怒られます。
image.png

複数行文字列リテラルは改行から必ず開始してください。

ということで、開始と終了する時には改行が必要です。

参考

[Swift]改行の仕方
How to create multi-line string literals



それでは、Swiftでの改行ライフをお楽しみください!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[iOS]モーダルを音速で閉じる

この記事は「[iOS]音速でモーダルを実装する」の続きです。
モーダル開いたらモーダル閉じたいよなぁ?という記事です。

バージョン

Swift 5.3
Xcode 12.1

モーダルを閉じる

モーダルを閉じるにはUIViewControllerのインスタンスメソッドであるdismissを使います。

実装

ファイルの追加

まず、モーダル用のViewControllerを追加します。
image.png
New File...から
image.png
Cocoa Touch Classを選択してNextをクリック
image.png
今回はModalViewControllerという名前にしてファイルを作成します。

ファイルとビューの関連付け

モーダル用のビューとファイルの関連付けを行います。
test.gif

閉じる用のボタンを配置

Modal用のビューにボタンを配置します。
image.png

モーダルを閉じる関数を書く

モーダルを閉じる関数を書きます。

ModalViewController.swift
import UIKit

class ModalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func closeModal() {
        self.dismiss(animated: true, completion: nil)
    }
}

ボタンと関数を関連付ける

ボタンと関数を関連付けます。

closemodal.gif

完成

完成だ!やった!!!
modaldemo.gif

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む