新型コロナウイルスに関係する内容の可能性がある記事です。
新型コロナウイルス感染症については、必ず1次情報として 厚生労働省 首相官邸 のウェブサイトなど公的機関で発表されている発生状況やQ&A、相談窓口の情報もご確認ください。※非常時のため、すべての関連記事に本注意書きを一時的に出しています。
見出し画像

SwiftUIの文法 その1 View

SwiftUIでは簡潔なコードでユーザーインターフェースを記述できます。
従来のコードよりも大幅に少ないコードで構築できるヒミツがあるはずです。
この記事ではまず、最もシンプルなビュー配置コードを調べ、SwiftUIが従来のSwift文法で書かれていることを確認します。

毎月札幌でiOSアプリ作りをアシストするセミナーをやっています。1時間にわたるセミナーの全内容を、物理的に参加できない方のためにnote上で公開します。

お知らせ
電子書籍『Swift5初級ガイド』をAppleのブックストアから出しました。サンプルは無料です。MacでもiPadでもiPhoneでも読めます。
WWDC2020で発表されたSwift 5.3対応の第6版がダウンロード可能です。(ご購入済みの場合は無料アップデートです)ブックストアから一度購入すると今後のアップデートは無料で読めます。

6宣伝store

iOSアプリ作りをアシストするセミナーは今後も月一回のペースで続ける予定です。(2020年3月以降COVID-19感染拡大防止のため休止しています)
詳細は connpass.com の 札幌Swiftでご確認ください。そして機会があればぜひ参加してください。
アプリ作りやプログラミング教育に関連する話題は 札幌Swift のfacebookページで発信しています。

・画像クリックで拡大表示できます
・画像を拡大表示中は画像の左右をクリックで画像だけを順に表示できます
・ソースコード部分は左右にスクロールできます
画像はXcode 11.2.1です。

有料記事です。購入でサンプルコードもダウンロードできます。


1 playgroundで確認できる

コードの確認は Xcode 11.2.1(11.2) のplayground で可能です。
playground を使った SwiftUIの実行は macOS 10.14.x でも macOS 10.15.x でも可能です。
playground でライブビューに表示するにはPlaygroundPage.current.liveView にViewControllerインスタンスを渡します。

SwiftUIのViewの場合は UIHostingController クラスのイニシャライザ UIHostingController(rootView:) を使い playground で表示できます。(iPad の Swift Playgrounds 3.1アプリでも実行できます)

1-1 SwiftUIと従来のコード例

SwiftUIのシンプルなコードを例に、従来のコードと比べましょう。

// 1行の文字列 フォントと色の指定のみ
import SwiftUI
import PlaygroundSupport

struct SampleView: View {
  var body: some View {
     Text("SwiftUIもSwiftだ!")
        .font(.title)
        .foregroundColor(.green)
  }
}

PlaygroundPage.current.liveView = UIHostingController(rootView: SampleView())

このSwiftUIコードは、ダイナミックタイプに対応したテキストスタイルと文字色を指定した1行の文字列を表示する playground 用のコードです。
(そのままiPadのSwift Playgrounds 3.1アプリでも実行できます)

Xcode 11.2.1 のplaygroundで実行した結果はこのようになります。

画像2

次はこれまでのコード、UIKitを使ったコード例を次に示します。

// UIKitの例
import UIKit
import PlaygroundSupport

class ViewController: UIViewController {
  let margin = 50
  let width1 = 300
  let height1 = 60
  override func viewDidLoad() {
     let box = CGRect(x: margin, y: margin, width: width1, height: height1)
     let topLabel = UILabel(frame:box)
     topLabel.text = "UIKitのラベル"
     topLabel.font = UIFont.preferredFont(forTextStyle:.title1)
     topLabel.textColor = .systemGreen
     view.addSubview(topLabel)
     view.backgroundColor = .white
  }
}

PlaygroundPage.current.liveView = ViewController()

(そのままplaygroundで使えるコードなので冗長な部分があります)
SwiftUIはコードの見た目がかなり違います。

冗長であっても指定が必要であることそのものが、SwiftUI開発のきっかけの一つであることを示していますね。

実行結果です。

画像3

表示位置が違いますが、座標の与え方で同じにできます。
文字スタイル(フォント)と文字色を指定した文字列を表示するコードとしては同じです。


2 宣言型シンタックス

AppleはSwiftUIのコードを「宣言型シンタックス」(Declarative Syntax)と呼んでいます。

確かにSwiftUIのコードには代入文がありません。が表示結果はほぼ同じです。

● 宣言型シンタックスであるSwiftUIはコードの組み方が変わる
● そのために新しく作られたフレームワークを使う
● 命令型ではない このためaddSubviewなどは使わない

SwiftUIではデフォルトが注意深く設定されています。
このため最小限のコードでそれなりの表示になり、調整が必要な場合のカスタマイズもシンプルです。

SwiftUIではレイアウトの自動化が最初から考慮されていて、何も指定しない場合は画面中央に自動で表示します。


3 ビュー宣言のコード

さらにシンプルに6行のコードを細かく見ていきましょう。(文字色の指定をはずしました)(サンプル1)

// 1行の文字列 フォント指定のみ
struct SampleView: View {
  var body: some View {
     Text("SwiftUIもSwiftだ!")
        .font(.title)
  }
}

最初の struct SampleView: View { はごく普通の型の定義です。
struct なのでコロンの次は準拠するプロトコルです。

SwiftUIのビューはViewプロトコルを継承したstructです。

var body: some View はstructのプロパティ です。
{...} が続いているので計算型プロパティ です。
bodyはViewプロトコルでは必須のプロパティ です。

型指定 some View の some はSwift5.1で利用可能になった新しいキーワードです。

some の付く場合はOpaque Type(不透明型)と呼ばれます。
型に厳格なSwift言語で型を抽象化しています。

3-1 body プロパティ

計算型プロパティ body では実は return が省略されています。

計算型プロパティはゲッターとセッターを設定し利用します。
ゲッターの通常の書式は get { return 計算値 }
セッターを書かない場合は get キーワードも省略可能になります。
上記の body では get キーワードも省略されています。

Swift5.1から関数や計算型プロパティで、処理が1行の場合は return キーワードが省略可能になりました。(Implicit Return

サンプル2のように return を書いても問題なく、表示は同じです。

// return を省略しないコード
struct SampleView: View {
   var body: some View {
     return Text("SwiftUIもSwiftだ!")
        .font(.title)
   }
}

return が省略できていたことから、次行の .font(.title) はもともと一つの行をあえて次の行に書いていたことがわかります。

3-2 Text("〜")はイニシャライザ

Text("SwiftUIもSwiftだ!") はText型のイニシャライザです。

init<S>(_ content: S) where S : StringProtocol

Text型は Equatableプロトコルと Viewプロトコルに準拠する struct です。

StringProtocol は Swift Standard Libraryのプロトコルです。
StringProtocol には String だけでなくSubstringも準拠しています。

そして .font(.title) はText型のインスタンスメソッドです。
サンプル3のように書き直してもコードの構造はまったく同じです。

// イニシャライザとメソッドを二つに分離
struct SampleView: View {
   var body: some View {
     let t0 = Text("SwiftUIもSwiftだ!")
     let t1 = t0.font(.title)
     return t1
   }
}

イニシャライザで生成したインスタンスを t0 に代入し、t0 に対してフォント指定したインスタンスを t1 に代入します。
bodyのインスタンスとして t1 を返しても表示はまったく同じことを確認してください。

3-3 .font(.title) は Text型を返すメソッド

Text型のfont(_:)インスタンスメソッドは Text型インスタンスを返します

// Text型 font インスタンスメソッドの宣言
func font(_ font: Font?) -> Text 

font(_:) メソッドは指定したフォントで表示する新しい Text 型インスタンスを返します
元のインスタンスには影響しません。

ViewプロトコルとText型はSwiftUIフレームワークに実装されたものですが、コードの書き方はSwift5.1の機能を使って省略されているだけで、通常のSwiftのコードそのままなのです。

t0.font(.title) は t0.font(Font.title) のFontを省略した書き方。
引数の型が決まっているので省略が可能。

ここで return t0 とすると、デフォルトのフォント(WWDCセッションでデフォルトのスタイルは.bodyと言っていました)で(小さな文字で)表示されます。
t0 は影響を受けていないことが確認できます。

この続きをみるには

この続き: 8,132文字
この記事が含まれているマガジンを購入する
単体で500円の記事10本を読めお得です。サンプルはXcodeのプレイグラウンドでもiPadのSwift PlaygroundsでもMacのPlaygroundsでも試せます。

まったく新しいSwiftUIに取り組むためのnoteをまとめました。 劇的にシンプルなコードでアプリが作れるしくみをプレイグラウンドを使っ…

または、記事単体で購入する

SwiftUIの文法 その1 View

快技庵 高橋政明

500円

この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
note.user.nickname || note.user.urlname

今後も記事を増やすつもりです。 サポートしていただけると大変はげみになります。

ありがとう!
4
古くからのMacプログラマ、現在はiOS向けに青空文庫リーダーアプリなどを作っている。「未経験者のための『コードを学ぼう』ガイド」『Swift5初級ガイド』など技術書執筆も行なっています。noteでは主にセミナーの内容を有料記事で公開しています。Twitterは@houhei

こちらでもピックアップされています

SwiftUIをためす
SwiftUIをためす
  • 11本
  • ¥1,000

まったく新しいSwiftUIに取り組むためのnoteをまとめました。 劇的にシンプルなコードでアプリが作れるしくみをプレイグラウンドを使って理解しよう。 note単体よりもリーズナブルに読めます。

コメントを投稿するには、 ログイン または 会員登録 をする必要があります。