くま's Tech系Blog

基本的には技術で学んだことを書き留めようと思います。雑談もやるかもね!

値型(struct)と参照型(class)について

今回はタイトルにもある通り、値型と参照型について説明していきます。

プログラミングの基礎的な概念だと思うので、理解しといて損はありません。

今回はSwiftで説明していきたいと思います。

値型

まずは値型について説明します。

値型は変数の中に実際の値が格納されます。正しく言うと、変数の領域に格納されます。

今回は値型であるstruct(構造体)で見てきたいと思います。

struct Human {
    var rank: UInt8
    var age: UInt8
}

上記のような構造体があるとします。説明しやすいように変数はUInt8にしています。

構造体(値型)の場合は値の全てがスタック領域に確保されます。

var kuma = Human(rank:1, age:23)

なので、上記のような宣言をした場合は 1 バイトのUInt8を二つ持っているので2バイト分(Human)の領域が確保されます。 2バイトの領域の最初の1 バイトには1が、次の 1 バイトには23が格納されるイメージです。イメージは下記です。

f:id:kumaskun:20200926222214p:plain

では、次の場合はどうなるでしょう?

var kuma = Human(rank:1, age:23)

var kumaCopy = kuma

kumaという構造体をkumaCopyという変数に代入しています。

次のようなイメージになります。

f:id:kumaskun:20200926223330p:plain

代入した変数はスタックに確保されるのですが、新しく確保された領域にコピーされた値が格納されます。 また、値型の場合変数には値そのものが入ります。

そのためコピー元の値を変更しても代入先の値は変わりません。

var kuma = Human(rank:1, age:23)

var kumaCopy = kuma

kuma.rank = 2

print(kumaCopy.rank)

上記のprintでは1が表示されます。

値型の場合スタックに値がコピーされ続けるのでデータ量の多い構造体の場合メモリを大きく食いつぶす可能性があります。

スタック領域は容量が小さいのですぐ使い切ってしまいます。

この場合スタックを使い切ってしまったエラーをスタックオーバーフローといい、クラッシュします。

参照型

参照型は別の場所に値を格納し、そのアドレス(どこに値を格納したか)を変数に格納します。

値型はスタック領域に格納されていましたが、参照型はヒープ領域に格納されます。

参照型ではクラスを元にして説明します。

class Human {
    var rank: UInt8
    var age: UInt8
    init(rank: UInt8, age: UInt8) { 
        self.rank = rank;
        self.age = age
    }
}

以下のようにして、オブジェクトを生成し変数に格納します。

var kuma = Human(rank:1, age:23)

クラス(参照型)はヒープ領域に確保されますが、その確保のされ方は値型がスタックに確保される時と同じです。

違うのはHuman(rank:1, age:23)が返す値が生成された領域の先頭アドレスということだけです。 つまり、kumaにはオブジェクトのアドレスが格納されています。 イメージは下記です。

f:id:kumaskun:20200927003759p:plain

このように参照型は値そのものではなく、オブジェクトへの参照を変数に格納します。

すると、値型で試した変数の代入を行った場合はどうなるでしょうか?

var kuma = Human(rank:1, age:23)

var kumaCopy = kuma

先にイメージをもとに説明したいと思います。

f:id:kumaskun:20200927004354p:plain

変数はスタックに確保され、変数宣言をすると新しくスタック領域に値のコピーが作成されます。

参照型の場合は変数にはアドレスという値がコピーされます。

指し示すアドレスは同じオブジェクトなのでkumaとkumaCopyは同じものとみなすことができます。

なので、コピー元の値を変更すると代入先の値も変更されます。

var kuma = Human(rank:1, age:23)

var kumaCopy = kuma

kuma.rank = 2

print(kumaCopy.rank)

上記のprintでは2が表示されます。

これは意図せず値が変わってしまう可能性があるので注意が必要です。

struct(値型)とclass(参照型)はどちらを使うのがいいのか?

ここまで値型と参照型を見てきて違いがわかったと思いますが、どちらを使った方がいいのかと思った方もいると思います。

個人的には、class(参照型)がメインで場合によってはstruct(値型)がいいと思います。

まずは、参照型からですが、参照型は代入のパフォーマンスだと思います。

var kuma = Human(rank:1, age:23)

var kumaCopy = kuma

上記は参照型の例なので、Humanはクラスです。

kumaCopykumaのメモリの先頭をコピーするだけです。32 bit アーキテクチャなら 4 バイト、 64 bit アーキテクチャなら 8 バイトのデータだけになります。

一方、値型の場合は値を全てコピーします。

値型で説明したときはrankageだけでしたが、下記のようにより多くのデータがある場合はその分コピーしないといけません。

struct Human {
    var data1: UInt8
    var data2: UInt8
    var data3: UInt8
    var data4: UInt8
    // 省略
   var data100: UInt8
}

上記のように変数が100個あると100個分コピーしないといけなくなり、その分の領域を確保しなくてはいけなくなりパフォーマンスが悪化する可能性があります。

structを使うのは比較的単純な値を扱うときのみの方がいい気がしました。

また、structは継承ができないため、継承する場合はclass一択です。

最後に、Swiftの標準ライブラリで提供される型(IntやString、配列など)はほぼすべてが値型という珍しい言語です。

メモリ領域

最後にメモリ領域について軽く述べたいと思います。

今まででスタック領域やヒープ領域などいきなり説明の中に出てきたと思います。軽く解説します。

スタック領域はメモリがA→B→Cの順で確保された場合、C→B→Aの順で解放される。メモリをいわゆるスタックで管理している。 処理ブロック({}で囲まれたブロック)を抜けると解放されます。 ヒープよりも割り当てられている領域が小さい。

ヒープ領域は確保されたメモリは明示的に解放しないとずっと留まり続ける。そのため気をつけていなければメモリリークを引き起こしクラッシュの原因になる。 自由なサイズのメモリを確保できます。

ヒープ領域の場合は、メモリを使い終わったら開放しないといけないのですが、Swiftでは自動的に解放されるようになっています。

この自動で解放してくれる仕組みをガベージコレクションと呼んでいます。 ガベージコレクションではヒープ領域に対して参照カウンタというものを持ちます。 参照カウンタとは、何個の変数から参照されているのかカウントするものです。

var kuma = Human(rank:1, age:23)

var kumaCopy = kuma

例えば、上記ではkumaとkumaCopyの2つでHumanは参照されています。 なので、参照カウンタは2になります。

この参照カウンタが0になったタイミングでオブジェクトは解放されます。どのようにするのでしょう?

kumaCopy = nil

nilはどこのアドレスも指していないという意味です。 そうすると参照カウンタが-1され1となります。

ただ、毎回毎回nilにする必要はありません。 変数は処理ブロックを抜けると解放されます。

つまり{}(ブロック)を抜けると変数は解放され、参照カウントが自動的に-1されるので、意識する必要がないです。

参照

Swiftで値型と参照型の違いを理解する

Structures and Classes

技術書典9を終えて

9/12(土)〜9/22(火)まで行われた技術書典9が終わったので振り返りたいと思います。

今回初めて1人で「モバイル詰め合わせ」という本を執筆して販売しました。

大したことを書いたわけではないから全然売れないだろうなあと思っていたのですが、終わってみると思ったより売れてうれしかったです!!

最初は謙虚じゃなく、本当に5冊売れればいいかなあと思っていましたが、目標は普通に超えたのでびっくりしました。

ただ、反省点が1つあるとすれば、表紙はちゃんとしたものにすれば良かったと思いました。

表紙がキレイな本はやっぱり売れている気がしました。

あと、物理本を準備すれば良かったと思いました。

オンライン即売会なんですが、意外に物理本が売り切れになることが多かったみたいです。

photoshopIllustratorが必要みたいで、時間的にも間に合わず見送ったのを後悔しました。

次の機会には準備をしたいと思いました。

何より1人で作ってみて売れたときの達成感はすごいものがありました。

技術同人誌は別の機会にも作りたいと思いました。

最後に宣伝です。

技術書典9は終わってしまいましたが、BOOTHで販売することにしました。

気になった方は下記より見ていってください!!

BOOTH -- くまさん研究所 『モバイル詰め合わせ』(https://kumalabo.booth.pm/items/2403310)

技術書典9にサークル参加しました

今回は告知をさせてください!!

初めて1人で技術同人誌を書きました。

そして、昨日(9/12)から始まった技術書典9というオンライン即売会で販売しています。

表紙を作る難しさを今回初めて痛感して、電子版のみの販売としています。(デザイナーに依頼するべきでした・・)

くまさん研究所というサークル名でモバイル開発についての本を執筆しました。

内容はAndroidのMVVM、SwiftUI、Flutterについてです。(主に導入部分がメインです)

後はオマケでAndroid11についても少し記載しています。(本当にオマケ程度です)

モバイル開発をしている方にももちろん読んでいただきたいですが、まだやったことない方にもこんな感じなのかと学びがあると思います。

まあつまり全人類の方に読んでいただきたいですwww

f:id:kumaskun:20200913133117p:plain
表紙はこんな感じです

今後BOOTH等で販売するかは未定ですが、とりあえずは技術書典オンラインマーケットでは販売します。

ぜひ見てみてください!!

くまさん研究所のモバイル詰め合わせはこちらから見れます

【Mac】VSCodeのショートカットまとめ

今回はVSCodeのショートカットをまとめたいと思います

エディタと言えば、VSCode(Visual Studio Code)であったりAtomサクラエディタ等を思い浮かべると思います

私はVSCodeをよく使うのですが、VSCodeは無料なんですが個人的にはクオリティが高く、拡張機能が充実していて重宝しています

また、iOSアプリ以外はある程度の言語が対応しているのもありがたいです

ただ、こういうエディタはいかにして効率的に使いこなすかが仕事をこなす鍵となるので、ショートカットや便利なものは学んでいきたいと思います

随時更新していく予定です、たぶん(まとめ系の記事では定型文となりつつある・・)

基本操作

キー 操作
⌘+C 行のコピー
⌘+X 行の切り取り
Option+↓ 現在カーソルが当たっている行を下に移動させる
Option+↑ 現在カーソルが当たっている行を上に移動させる
Shift+⌥+↑ 現在カーソルが当たっている行を上にコピー
Shift+⌥+↓ 現在カーソルが当たっている行を下にコピー
⌘+↑ ファイルの先頭に移動
⌘+↓ ファイルの末尾に移動
⌘+F 検索
Option+⌘+F 置換
⌘+G 次を検索
Shift+⌘+G 前を検索
⌘+/ コメントアウトする(コメントアウトされている行はコメントアウトを解除)
⌘+] インデントの追加
⌘+[ インデントの削除
⌘+Enter 下に行追加
Shift+⌘+ Enter 上に行追加

エディタ・ウィンドウ操作

キー 操作
Shift+⌘+N 新しいウィンドウを開く
Shift+⌘+W ウィンドウを閉じる
⌘+W エディターを閉じる
⌘+1 左のエディターにフォーカス
⌘+2 サイドエディターにフォーカス
Option+⌘+← 左隣のエディターにフォーカス
Option+⌘+→ 右隣のエディターにフォーカス

ファイル操作

キー 操作
⌘+N 新しいファイルを作成
⌘+S ファイルを保存
Shift+⌘+S 名前をつけて保存
⌘+K+W ファイルを閉じる
⌘+2 サイドエディターにフォーカス
Option+⌘+← 左隣のエディターにフォーカス
Option+⌘+→ 右隣のエディターにフォーカス
Ctrl+G 指定の行に移動
⌘+P 指定のファイルに移動
Shift+⌘+O 指定のシンボルに移動
Shift+⌘+M エラーと警告の表示

画面表示

キー 操作
Shift+⌘+= ズームイン
⌘+- ズームアウト
⌘+B サイドバー表示・非表示
Shift+⌘+C 新しいコマンドプロンプトを開く
Shift+⌘+E エクスプローラーの表示
Shift+⌘+D デバッグ画面の表示
Shift+⌘+F 検索画面の表示
Shift+⌘+J 詳細検索の表示
Shift+⌘+E エクスプローラーの表示
Shift+⌘+U アウトプット画面を開く

その他

キー 操作
⌘+, ユーザー設定を開く
⌘+B サイドバー表示・非表示
Shift+⌘+C 新しいコマンドプロンプトを開く
Shift+⌘+E エクスプローラーの表示
Shift+⌘+D デバッグ画面の表示
Shift+⌘+F 検索画面の表示
Shift+⌘+J 詳細検索の表示
Shift+⌘+E エクスプローラーの表示
Shift+⌘+U アウトプット画面を開く

上記以外にも多くのショートカットが存在します

その中にはコマンドが決まっていないものもあり、カスタマイズすることが可能です。

CodePreferencesKeyboard Shortcutsで設定画面が開きます

f:id:kumaskun:20200829093859p:plain

この画面でデフォルトのコマンドの変更やコマンドが決まっていないものを決めることができます

ショートカットを使いこなすことは効率化というテーマの中で基本的な部分なので、試してみるといいかもしれません!!

忘れやすいiOSの証明書関連を思い出す

PCを変更したことでせっかくなので、証明書を作り直してみました

意外に忘れてしまっていたので(年に1回くらいなので)、メモのために今回記事を書きます

①証明書生成

まずは、証明書生成を行います

Macのアプリケーション→ユーティリティ→キーチェーンアクセス.appを開きます

キーチェーンアクセスを開いたら、上のほうにあるメニューのキーチェーンアクセス→証明書アシスタント→認証局に証明書を要求を選択します

選択すると下記画面が表示されるはずです

f:id:kumaskun:20200726232137p:plain

ユーザーのメールアドレスは開発者のメールアドレスを入力

通称は適当な名前を入力します

CAのメールアドレスは無記入で大丈夫です (要求の処理をディスクにするので必須ではない)

要求の処理には「ディスクに保存」と「鍵ペア情報を指定」にチェックを入れて続けるをクリックして下さい

次の画面では、CertificateSigningRequest.certSigningRequestをデスクトップに保存するように設定してください

続けると鍵のサイズとアルゴリズムを選択する画面が表示されるので、鍵のサイズは2048ビットアルゴリズムRSAを選択してください

f:id:kumaskun:20200727005319p:plain

続けると、CertificateSigningRequest.certSigningRequestがデスクトップに保存されます

②開発者証明書の作成

次に開発者用の証明書を作成します

Apple DeveloperのCertificates, Identifiers & Profilesで行います

新規作成の場合はCertificatesのとなりの+ボタンをクリックします

f:id:kumaskun:20200727010643p:plain

すると、作成する証明書の種類を選ぶ画面が出てくるかと思います

f:id:kumaskun:20200727010927p:plain
証明書の種類を選ぶ画面

開発用の場合はiOS App Development、製品用の場合はiOS Distributionを選択します

するとファイルをアップロードする画面が表示されるので、Choose Fileの箇所に①で作ったCertificateSigningRequest.certSigningRequestをアップロードしましょう

f:id:kumaskun:20200727011331p:plain

アップロードが成功するとContinueがクリックできるようになるはずなので、クリックすると開発者用の証明書がダウンロードできるようになります

ダウンロードすればここまでの手順は完了です

➂キーチェーンアクセスに登録

最後に、開発者用の証明書をキーチェーンアクセスに登録します

②でダウンロードしたファイルは、開発用であればios_development.cer・製品用はios_distribution.cerという名前でダウンロードされているはずです

ダブルクリックしてキーチェーンアクセスに反映させます

ダブルクリックしたら、キーチェーンアクセスに新しく登録されているのを確認してください

あと、Apple DeveloperのCertificatesにも反映されているか確認してみてください

あまりやることない作業だと思いますが、たまにやることがあり毎回どこかしらで詰まってしまう内容だったので、まとめました

チーム開発とかだと秘密鍵の管理などまだまだ大変なことがありますが、ここを理解していれば開発はできると思います

SwiftUIでjsonデータを取り扱ってみる

今回はjsonデータを使って画面表示を行ってみたいと思います

APIを使って戻り値のjsonデータをパースして値を取得するというのはモバイル開発では必ずと言っていいほどやる処理だと思うので、学んでいきます!!

jsonデータの準備

今回は実際にAPIを使ってではなく、jsonのデータを用意して、そのデータを取得するようにします

今回は人間の情報をjsonで定義します

Resourceフォルダを新しく作成して、HumanData.jsonを作成しました

[
    {
        "name": "Tom",
        "age": "28",
        "city": "AAAAA",
        "sex": "M",
        "id": 1001,
        "extra": {
            "blood": "O",
            "hand": "left"
        },
    },
    {
        "name": "Nick",
        "age": "30",
        "city": "BBBBB",
        "sex": "F",
        "id": 1002,
        "extra": {
            "blood": "A",
            "hand": "left"
        },
    }
]

このjsonデータをモデルにしたものを新しく作成します

Modelフォルダを新しく作成してHuman.swiftを作りました

import SwiftUI

struct Human: Hashable, Codable {
    var id: Int
    var name: String
    var age: String
    var city: String
    var sex: String
    var extra: Extra
}

struct Extra: Hashable, Codable {
    var blood: String
    var hand: String
}

また、定義したjsonデータをモデルに変換する処理をModelフォルダ配下にData.swiftとして作成します

import UIKit
import SwiftUI
import CoreLocation

let humanData: [Human] = load("HumanData.json")

func load<T: Decodable>(_ filename: String) -> T {
    let data: Data
    
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }
    
    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }
    
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

上記はどちらかというとSwiftの解説になるので、別の機会にできたら行いたいですが、勉強になるのでみてみるといいかもしれません

チュートリアルからダウンロードできるものを少し改良しました

ここまででデータの準備はできたので、あとは表示させるクラスを準備します

HumanRow.swiftを作成します

import SwiftUI

struct HumanRow: View {
    
    var human: Human
    
    var body: some View {
        Text(human.age)
    }
}

struct HumanRow_Previews: PreviewProvider {
    static var previews: some View {
        HumanRow(human: humanData[0])
    }
}

表示するデータであるhumanをプレビューに渡すことで表示できるようになります

f:id:kumaskun:20200808230741p:plain
プレビュー

また、下記のようにGroupで囲むことで複数表示できます

import SwiftUI

struct HumanRow: View {
    
    var human: Human
    
    var body: some View {
        Text(human.age)
    }
}

struct HumanRow_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            HumanRow(human: humanData[0])
            HumanRow(human: humanData[1])
        }
    }
}

f:id:kumaskun:20200808231645p:plain

これだと複数のプレビューができてしまいます

一般的なリストは1つのプレビューに複数のリストを表示させると思うので、これだと想像していたのとは違いました

では、リスト表示はどうすればいいのでしょうか?

これはちょっとした発想の転換ですが、Listのクラスを列を表示させれば実現できます

import SwiftUI

struct HumanList: View {
    var body: some View {
        List {
            HumanRow(human: humanData[0])
            HumanRow(human: humanData[1])
        }
    }
}

struct HumanList_Previews: PreviewProvider {
    static var previews: some View {
        HumanList()
    }
}  

f:id:kumaskun:20200808233246p:plain

ただ、これだと100個データがあったら100行書かないといけなくなり大変です

for文で回すような処理が欲しいところですね

そこで下記のようにするとクロージャーから列を取得でき、それを表示できます

import SwiftUI

struct HumanList: View {
    var body: some View {
        List(humanData, id: \.name) {human in
            HumanRow(human:human)
        }
    }
}

struct HumanList_Previews: PreviewProvider {
    static var previews: some View {
        HumanList()
    }
}

f:id:kumaskun:20200809030357p:plain

上記だとユニークなキーを元にして値を取得していますが、モデルでIdentifiableプロトコルを適用させればキーを使わずに表示させることが可能です

import SwiftUI

struct Human: Hashable, Codable, Identifiable {
    var id: Int
    var name: String
    var age: String
    var city: String
    var sex: String
    var extra: Extra
}

struct Extra: Hashable, Codable {
    var blood: String
    var hand: String
}
import SwiftUI

struct HumanList: View {
    var body: some View {
        List(humanData) {human in
            HumanRow(human:human)
        }
    }
}

struct HumanList_Previews: PreviewProvider {
    static var previews: some View {
        HumanList()
    }
}

ユニークなデータであることが前提ではありますが、これだと少し簡略にできますね!

最後にリストにNavigation Linkを付けたいと思います

import SwiftUI

struct HumanList: View {
    var body: some View {
        NavigationView {
            List(humanData) {human in
                NavigationLink(destination: HumanDetail()) {
                    HumanRow(human:human)
                }
            }
            .navigationBarTitle(Text("Human"))
        }
    }
}

struct HumanList_Previews: PreviewProvider {
    static var previews: some View {
        HumanList()
    }
}

HumanDetailというクラスを空で作った上で上記のようにすれば、Navigation Linkが追加されます

また、navigationBarTitleで上に表示するタイトルを決めることができます

これはスコープを意識しないとたまに間違えてしまうんですが、NavigationView内でListの次に書かないとうまく表示されないです

ついでに血液型も追加して表示してみたらこんな感じでした

f:id:kumaskun:20200809033357p:plain
Navigation Linkのイメージ

これでjsonの扱いはある程度できることがわかりました!!

ただ、細かいサイズの指定や場所の指定などできるのかが今の自分の学びの中では未知数なので、調べていきたいです

SwiftUIで画像にいろいろ手を加えてみる

以前、SwiftUIでテキストを配置したり色を変更したりしました

今回は画像にいろいろ手を加えるというのをSwiftUIで試してみたいと思います

まずはリソース(画像)を追加します

f:id:kumaskun:20200728231702p:plain
画像の追加

この画像を表示させるためにはImageの引数に画像のリソース名を指定すれば表示されます

f:id:kumaskun:20200728231908p:plain

少し見にくいかもしれないですが、画像をクリックして見てみてください!

上記はシンプルに画像を表示させていますが、変化を加えるのも可能です

struct IconImageView: View {
    var body: some View {
        Image("Icon")
            .resizable()
            .clipShape(Circle())
    }
}

resizable()で画像サイズをフレームサイズに合わせて、.clipShape(Circle())で画像を円形にします

f:id:kumaskun:20200728233031p:plain

また、枠線と影をつけることができます

struct IconImageView: View {
    var body: some View {
        Image("Icon")
            .resizable()
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.blue, lineWidth: 4))
            .shadow(radius: 10)
    }
}

こうすることで、青色の枠線と影を画像に追加することができました

f:id:kumaskun:20200728233528p:plain

さらにフレームのサイズは変更できるので、画像がはみ出てしまうのもうまく調整できます

struct IconImageView: View {
    var body: some View {
        Image("Icon")
            .resizable()
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.blue, lineWidth: 4))
            .shadow(radius: 10)
            .frame(width: 300, height: 300)
    }
}

frame(width: 300, height: 300)というようにwidthとheightを指定できるので、プレビューを見ながらうまい具合に調節できます

f:id:kumaskun:20200728234206p:plain

ちなみにはみ出してしまった分は.clipped()を使うことにより、切り取ることも可能です

HTML・CSSを触っている感覚に何度か陥りました!

では、画像とテキストの組み合わせはどうするでしょうか??

SwiftUIのbody propertyは単一のviewしか返さないので複数のviewを扱うためにStackを使います

VStackHStackはそれぞれ垂直と水平方向、あるいは前後に組み合わせてStackに組み入れグループ化することができます

struct IconImageView: View {
    var body: some View {
        Image("Icon")
                .resizable()
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.blue, lineWidth: 4))
                .shadow(radius: 10)
                .frame(width: 300, height: 300)
            
        Text("Hello World")
            .font(.largeTitle)
            .foregroundColor(Color.red)
    }
}

上記はエラーになるパターンです

ImageTextという2つのViewがあり、bodyの戻り値がViewのためエラーが発生します

なので、Vstackで囲ってあげれば解消されます

struct IconImageView: View {
    var body: some View {
        VStack {
            Image("Icon")
                .resizable()
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.blue, lineWidth: 4))
                .shadow(radius: 10)
                .frame(width: 300, height: 300)
            
            Text("Hello World")
            .font(.largeTitle)
            .foregroundColor(Color.red)
        }
    }
}

f:id:kumaskun:20200801151058p:plain
VStackのプレビュー

画像の取り扱いはここまでとします

以前取り上げたテキストの表示と組み合わせることで最低限のUIは作れるのではないかと感じました

ただ、実務レベルとなると。。。もう少し時間がかかりそうな気がしました

テキストの表示の記事はこちら

SwiftUIを触ってみる

今回は前から気になっていたSwiftUIを触ってみようと思います

今回の記事は、SwiftUIのチュートリアルをベースにしています

プロジェクト作成

まずはプロジェクトを作ってみましょう!

プロジェクトを新規で作成する際にSingle View App を選択します

f:id:kumaskun:20200725182233p:plain

Nextをクリックしたら、User InterfaceSwiftUIを選択します

f:id:kumaskun:20200725182346p:plain

それ以外は今までと同じようにすればSwiftUI用のプロジェクトが作成されます

プロジェクトの中身

プロジェクトが無事に作成されたら、次は中身をみていきましょう!

プロジェクトを開いて見ると、Storyboardに慣れている人はMain.storyboardがないことに戸惑うかもしれません

SwiftUIはキャンバスのプレビューでアプリの表示や動作を確認してしながらSwiftファイルに直接コードを書いていく形式なので、ストーリーボードは存在しません

最初に画面を作るのはContentView.swiftというビューファイルです

下記の赤枠を押すことでプレビューが表示できるオプションが表示されます(MacのOSバージョンが10.15以上の場合)

f:id:kumaskun:20200725185825p:plain

Canvasを選択して、Resumeをクリックしることでビルドエラーがなければプレビューが表示されます

f:id:kumaskun:20200726125749p:plain

f:id:kumaskun:20200726131842p:plain
プレビュー

SwiftUIのViewファイル(ここでのContentView.swift)は下記2つで構成されています

・Viewの内容やレイアウトの宣言

・プレビューの設定

当然ながら、プレビューで表示されている"Hello World"を書き換えると、書き換えた文言で表示されます

文字のカスタマイズ

文字をもう少しカスタマイズしたい場合はどうすればいいのでしょうか?

プレビュー画面のテキストをクリックしながらcommandボタンを押すとオプションが表示されます

f:id:kumaskun:20200726201907p:plain

そこで、show SwiftUI inspectorを選択するとサイズやフォントが変更できるオプションが表示されます

f:id:kumaskun:20200726202214p:plain

例えば、fontをLarge Title、ColorをRedにするとプレビューにも反映され、ソースコードも自動で反映されます

f:id:kumaskun:20200726202520p:plain

今のところ自分でソースコードを追加してません!

リストにしたりもできるので、簡単なUIを作成するくらいならソースコードを書く必要がないかもしれません

テキストのオプションを追加していく場合はチェーンのようにオプションを追加していくことで実現できます

また下記のようにソースコードのTextの部分でcommand + クリックで同じように設定ができます

f:id:kumaskun:20200726203159p:plain

今回はここまでとします

SwiftUIは気になるトピックなので、また続きは別記事を書こうと思っています!