SwiftUI

SwiftUIをまとめた記事
NavigationSplitViewの"Simultaneous accesses to..."クラッシュの回避方法
iOS

NavigationSplitViewの"Simultaneous accesses to..."クラッシュの回避方法

iOS 16から登場したNavigationSplitViewとSwift 5.9から登場したmacroの@Observableの組み合わせでクラッシュが発生することがあります。 この記事ではその回避方法を説明します。 動作環境 * Xcode 15 * iOS 17 クラッシュが起こる原因 ListにはSelectionValueと呼ばれる選択された保持するパラメーターが定義されています。 このSelectionValueはHashableを準拠したインスタンスを指定します。 @MainActor struct List<SelectionValue, Content> where SelectionValue : Hashable, Content : View * https://developer.apple.com/documentation/swiftui/list/#Supporting-selection-in-lists そして、NavigationSplitViewとListのSelectionValue、そしてNavigat
4 min read
UITextViewで独自のEdit Menuを表示する
iOS

UITextViewで独自のEdit Menuを表示する

実行環境 * Xcode 14.2 * iOS 16 iPhoneのメモアプリで、テキストを長押しすると出てくるメニュー。 あれを自分で作るにはどうすればいいのかを調べてみました。 そもそもあのメニューの名前はなんだろうと調べたところ、Human Interface GuidelinesにはEdit Menuという名前で紹介されていました。 Edit menus | Apple Developer DocumentationAn edit menu lets people make changes to selected content in the current view, in addition to offering related commands like Copy, Select, Translate, and Look Up.Apple Developer Documentation Edit Menuの表示
3 min read
[SwiftUI] GeometryReaderでメソッド/関数を実行したい!
iOS

[SwiftUI] GeometryReaderでメソッド/関数を実行したい!

実行環境 * Xcode 12.5 GeometryReaderでViewのサイズを取得する [SwiftUI] GeometryReaderでViewのサイズを知る [https://blog.personal-factory.com/2019/12/08/how-to-know-coorginate-space-by-geometryreader/] で解説したとおり、SwiftUIでViewのサイズを取得するにはGeometryReaderを使います。 GeometryReaderのハンドラーから渡されるGeometryProxyのインスタンスでViewのサイズがわかります。 struct LocalVariableView: View { var body: some View { GeometryReader { proxy in Text("\(proxy.frame(in: .local).debugDescription)") } } } struct LocalVariableView_
2 min read
Clubhouseのスーパー楕円をSwiftUIで作る
iOS

Clubhouseのスーパー楕円をSwiftUIで作る

近年流行りだした音声SNS, Clubhouse [https://www.joinclubhouse.com/]。 デザインの特徴の1つにふわっとした丸みを帯びた楕円のアイコンがあります。 これは「スーパー楕円」と言われているそうです。 丸よりも丸みを感じる!? スーパー楕円の魅力とデザイン | Spinners Inc. [https://www.spinners.work/posts/kudakurage-superellipse-desgin/] この楕円を@tokorom [https://twitter.com/tokorom]さんがUIKitで実装してました。 スーパー楕円UIをiOS+Swiftで実装する | Spinners Inc. [https://spinners.work/posts/swift-superellipse/] この記事を読んでSwiftUIでも作りたくなったので、作ってみます。 実行環境 * Xcode 12.2 * iOS 14.2 実装方針 tokoromさんと同じようにもと記事 [https://www.spinner
4 min read
SwiftUIで開閉式メニューの作り方
iOS

SwiftUIで開閉式メニューの作り方

SwiftUIで下からニュッと表示する開閉式メニューの作り方を解説します。 > この記事は私が2020年12月22日に発表した資料、 「SwiftUIで作る開閉式メニュー [https://speakerdeck.com/satotakeshi/swiftuidezuo-rukai-bi-shi-meniyu] 」を記事化したものです。 動作環境 この記事は以下の環境で動作を確認しています。 * Xcode 12.2 * iOS 14.2 開閉式メニューを作ろう 今回作る開閉式メニューの動きをgifでみてみましょう。 親Viewを作る まずは親Viewを作りましょう。 struct ContentView: View { @State var isShowMenu = false var body: some View { ZStack { Button(action: { withAnimation { isShowMenu.toggl
4 min read
SwiftUIのデータ管理 Single Source of Truth編
iOS

SwiftUIのデータ管理 Single Source of Truth編

SwiftUIでアプリを開発していると@Stateや@Bindingの使い分けについて迷ったりしていませんか? SwiftUIではデータを管理するProperty Wrapperがたくさんあります。 @State、@Binding、@StateObject、@ObservedObjectなどなどです。 Property Wrapperそれぞれの特徴を理解できれば、SwiftUIのアプリ開発がはかどるでしょう。 今回はSwiftUIのデータ管理に欠かせないSingle Source of Truthという考え方について解説します。
3 min read
UITableViewをコードで実装する最速の方法
iOS

UITableViewをコードで実装する最速の方法

UITableViewでリスト表示を実装するさい、よくやるやり方は、StoryboardやXibファイルでCellを作って、そのidentifierをView Controllerで指定する方法です。 ですが、UITableViewCell標準の表示で十分な場合にファイルが分かれるのは面倒です。 なんとかコードで済ます方法がないかと探したらありましたのでご紹介します。
2 min read
[iOS 14]WidgetでDeep Link作成
iOS

[iOS 14]WidgetでDeep Link作成

iOS 14からWidgetという機能が登場しました。これはアプリを起動しなくてもHome画面にアプリ情報をユーザーに届けられる機能です。 今回はWidgetをタップした時に特定のアプリ画面が開けるようにする、Deep Linkの作成方法について解説します。 検証環境 * Xcode 12.2 * iOS 14.2 WidgetとDeep Link Widgetをタップすると何も実装しなければ、本体アプリが起動されます。 しかし、Widgetに表示されているコンテンツと関連した画面に遷移できればユーザー体験が向上します。 そのためにはWidgetにDeep Linkを作る必要があります。 Widgetのサイズとリンクの数について まず最初にWidgetのサイズとリンクの数についてお話します。 開発者が作れるWidgetの大きさはSmall, Medium, largeの3つです。 実はWidgetはサイズによっておけるリンクの数が決まっています。 Smallサイズはひとつだけで、MediumサイズとLargeサイズは複数置くことができます。 例えば、Appleの
3 min read
[iOS 14] Widgetでカウントダウン
iOS

[iOS 14] Widgetでカウントダウン

WidgetのViewを更新するにはTimelineProviderプロトコルのgetTimelineメソッドを実装してタイムラインという何時何分にどんなデータでViewを更新するのかをあらかじめWidgetKitに伝える必要があります。 Todoアプリなどでイベントをカウントダウン表示したい場合を想定します。 毎秒更新するようにタイムラインを作成すればうまくいくかと思いきや、各アプリによってWidgetを更新できる回数は決まっています。 TimelineProviderのドキュメントにはこう書かれています。 > Each configured widget receives a limited number of refreshes every day. Several factors affect how many refreshes a widget receives, such as whether the containing app is running in the foreground or background, how frequently the widge
2 min read
iOS

[SwiftUI]半透明の色を設定する

検証環境 * Xcode 11.6 * iOS 13.6 半透明の色を設定する Colorに.opacity修飾子メソッドを実行すると色の透明度を設定することができます。 Rectangle() .foregroundColor(Color.black.opacity(0.5)) 50%の透明度で指定しています。 キャプチャはこちら。 20%ぐらいだとこのぐらい。 .foregroundColor(Color.black.opacity(0.2)) 100%だとこのぐらいの色になります。 .foregroundColor(Color.black.opacity(1)) まとめ 背景色などを半透明にしたいなと思ったときに.opacityは使えそうです。 宣伝 インプレスR&D社より、「1人でアプリを作る人を支えるSwiftUI開発レシピ」発売中です。 「SwiftUIでアプリを作る!」をコンセプトにSwiftUI自体の解説とそれを組み合わせた豊富なサンプルアプリでどんな風にアプリ実装すればいいかが理解できる本となっています。 iOS 14対
1 min read
PMとデザイナーが知るべきiOS 14 新機能Widgetのすべて
iOS

PMとデザイナーが知るべきiOS 14 新機能Widgetのすべて

6月にWWDC20が発表され、次期iOS 14にはWidgetという新機能が登場することが判明しました。 Apple、iOS 14でiPhoneの体験を刷新 [https://www.apple.com/jp/newsroom/2020/06/apple-reimagines-the-iphone-experience-with-ios-14/] より抜粋 この記事ではWidgetのUI/UXをまとめます。 PMとデザイナーが「Widgetを自プロダクトに導入する」にあたって、「Widgetがどういうものなのか」を理解するためにこの記事が役に立つでしょう。 記事の内容はUI/UXに絞っているため技術的な観点からの言及は少ないです。 予めご了承ください。 免責 8月10日現在、WidgetについてはApple Beta Software Programにあたるため、スクリーンショットを独自でとることはNDAの観点から避けなければいけません。 この記事ではAppleの公式サイト、WWDCのVideoからキャプチャーを利用いたします。 引用と判別ができるよう、キャプチャーを取得した
9 min read
[SwiftUI]選択可能なUIコンポーネントの作り方【ラジオボタン偏】
iOS

[SwiftUI]選択可能なUIコンポーネントの作り方【ラジオボタン偏】

前回 [SwiftUI]選択可能なUIコンポーネントの作り方【複数選択偏】 [https://blog.personal-factory.com/2020/07/11/how-to-create-selectable-ui-component-by-swiftui-in-multiple/] で複数選択ができるUIコンポーネントをSwiftUIで作る方法を解説しました。 今回はHTMLのラジオボタンのように複数あるViewの内一つのみ選択するコンポーネントを作ってみます。 まずは動きをみていきましょう。 赤、緑、青のビューがあって、赤をタップすると黒枠が追加されて選択状態ということがわかります。デバックエリアにも「selected box is red」と出力されます。 他のビュー、例えば緑をタップすると、赤のビューの黒枠は消えて、緑のビューが黒枠でおおわれるようになるというしだいです。 選択するViewのタイプを定義 ユーザーが何を選択したかを判定できるようにBoxTypeというenumを定義します。 enum BoxType: String { case unkn
4 min read
[SwiftUI]選択可能なUIコンポーネントの作り方【複数選択偏】
iOS

[SwiftUI]選択可能なUIコンポーネントの作り方【複数選択偏】

人はときにタップをしたらそのビューを選択状態にするコンポーネントが必要になることがあります。 ちょっと手こずったのでブログに作り方を残します。 今回は複数選択する場合を解説したいと思います。 実行環境 * Xcode 11.5 * iOS 13.5 複数選択可能なUIコンポーネント HTMLだとチェックボックスがいい例ですが、複数選択できるコンポーネントがあると素敵ですよね。 作ってみましょう。 赤、緑、青のViewがあって、タップするとViewに黒枠が追加されて選択状態がわかるようになります。 またコンソールにもタップされたら「red is selected」 。もう一度タップすると「red is not selected」というようなメッセージができるようにしています。 ViewModelの定義 まずはデータまわりを定義していきましょう。 MultipleSelectableViewModelというクラスを定義します。 final class MultipleSelectableViewModel: ObservableObject { @Publish
4 min read
【WWDC20】Introduction to SwiftUI の雑メモ
Swift

【WWDC20】Introduction to SwiftUI の雑メモ

WWDC20のIntroduction to SwiftUIをみました。 雑にメモを残そうと思います。 https://developer.apple.com/wwdc20/10119 * ライブラリーからdrop and dragでViewコンポーネントをeditorに入れられる * ライブラリーペインからcornerRadius modifierをキャンバスに落とす * コードに追加される * previewのresumeショートカット * ⌘+option+P * Extract Subviews * View実装が大きくなったとき使う。追加でViewのレイアウトを増やしたい。でもすでにたくさん実装していてコードが大きくなっている。 * Extract Subviewsを使ってViewを新しい型に切り分けることができる * spacer、スペースが可能な領域までできるだけ広がる。 * テキストを真ん中によせるために今回は使った。 * Detai
4 min read
WWDC20 SwiftUI API追加まとめ
SwiftUI

WWDC20 SwiftUI API追加まとめ

WWDC20 [https://developer.apple.com/wwdc20/] のkeynoteが終わり、Appleの開発者ドキュメントが更新されました。 https://developer.apple.com/documentation/technologies?changes=latest_minor SwiftUIのAPIでどんな更新があったのかをみていきたいと思います。 App Structure and Behavior Built-in Scene Types 新規追加。 ついにSwiftUIだけでアプリがすべて作れるようになります! 伝統的にアプリ状態をハンドルしていたAppDelegateやiOS 13から導入されたSceneDelegateが不要になります。 これはめでたい。 https://developer.apple.com/documentation/swiftui/app-structure-and-behavior?changes=latest_minor * protocol App [https://developer.ap
3 min read
SwiftUIアプリをVIPERアーキテクチャーで作り画面遷移処理をまとめる
iOS

SwiftUIアプリをVIPERアーキテクチャーで作り画面遷移処理をまとめる

この記事では画面遷移処理をView実装から引き剥がす方法としてVIPERアーキテクチャを解説し、実際にSwiftUIアプリケーションに適応します。 ログイン画面やNavigation ViewのPush遷移, Tab Bar表示、アラートやモーダル表示など、アプリケーションで利用する画面遷移処理をどう扱うかをみていきましょう。
10 min read
iOS 13でのNavigationBarのカスタマイズ方法
iOS

iOS 13でのNavigationBarのカスタマイズ方法

NavigationBarをカスタマイズする方法がiOS13から変わったそうです。 ご丁寧にAppleからサンプルアプリ [https://developer.apple.com/documentation/uikit/uinavigationcontroller/customizing_your_app_s_navigation_bar] が提供されているのでそれを確認していけばカスタマイズできそうです。 今回の記事ではAppleのサンプルアプリをみつつ、NavigationBarのカスタマイズ方法を解説します。 実行環境 * Xcode 11.4.1 Customizing Your App’s Navigation Bar AppleはCustomizing Your App’s Navigation Bar [https://developer.apple.com/documentation/uikit/uinavigationcontroller/customizing_your_app_s_navigation_bar] という記事を公開し、NavigationBar
4 min read
[SwiftUI]iPad上でNavigaitonViewでSplitViewを実現
iOS

[SwiftUI]iPad上でNavigaitonViewでSplitViewを実現

SwiftUIでSplitViewを表現する方法がNavigationでできるようなのでまとめます。 少しトリッキーなコードになりますが、少ないコードでSplitViewレイアウトを実装することができます。 検証環境 * Xcode 11.4 Split Viewとは? 設定アプリのように、Viewが2つ並びで左右に別れているレイアウトです。 設定アプリでは、左側のペインに設定項目が並び、それらをタップすると右側ペインに詳細画面が表示されます。 NavigationViewでSplitView SwiftUIではNavigationViewでSplitViewを表現できるようです。 NavigationView { NavigationLink(destination: Text("Detail")) { // ③ Text("Master") // ① } .navigationBarTitle("Nav", displayMode: .large) Text("First Screen") // ② } .paddin
2 min read
「1人でアプリを作る人を支えるSwiftUI開発レシピ」という同人誌を書きました #技術書典
iOS

「1人でアプリを作る人を支えるSwiftUI開発レシピ」という同人誌を書きました #技術書典

WWDC 19から登場した新しいユーザーインターフェースフレームワークSwiftUI。 これを使えば、アップルプラットフォーム(iOS/iPadOS/macOS/tvOS)でアプリを楽に作ることができます。 発表から半年以上がたち、徐々にSwiftUIでアプリ開発をする事例も出てきました。 ですが、世の中に出ているSwiftUIの解説記事はまだまだ断片的で、ひとつのアプリを開発するノウハウを説明するところまではいってないと感じています。 「1人でアプリを作る人を支えるSwiftUI開発レシピ」ではアプリ開発に焦点をあてたSwiftUI解説本です。実践的なアプリレシピを紹介することで、自分でアプリを作るときにもどうアプリを組み立てていったらいいのかが理解できるようになります。 「本書で学べること」 * データバインディング * MVVMでのアーキテクチャ * SwiftUI自体の使い方(レイアウトシステム、座標取得) * SwiftUIでは足りない部分を補う方法 掲載レシピ GitHubAPIリポジトリ検索アプリ 今ではどのアプリにも必須の機能であるURLSessi
2 min read
SwiftUIでドロップシャドー
iOS

SwiftUIでドロップシャドー

SwiftUIでドロップシャドーをつけるにはshadow修飾子をつければ良いです。 Text("Text") .shadow(color: Color.red, radius: 10, x: 0, y: 0) しかし、親Viewにshadowをつけると子ビューそれぞれにドロップシャドーついてしまいます。 VStack() { Text("Text") .background(Color.red) .padding() Text("Text") .background(Color.purple) .padding() } .padding() .background(Color.white) .shadow(color: Color.red, radius: 10, x: 0, y: 0) 親ビューのみにドロップシャドーをつける場合は2つ方法があります。
2 min read
[SwiftUI] GeometryReaderで特定のViewをキャプチャする
SwiftUI

[SwiftUI] GeometryReaderで特定のViewをキャプチャする

前回SwiftUIでお絵かきアプリ [https://blog.personal-factory.com/2019/11/30/draw-application-by-swiftui/] の記事で指をドラッグすることでPathを作りお絵かきアプリを作りました。 作った絵は保存したくなりますよね? というわけで今回はSwiftUIで特定のViewをキャプチャして画像にする方法を解説します。 サンプルコード 今回解説するサンプルコードはこちらです。 https://github.com/SatoTakeshiX/SwiftUICatalog/blob/master/GeometryReaderSample/GeometryReaderSample/DrawEditor.swift アプリを試してみたい方は https://github.com/SatoTakeshiX/SwiftUICatalog をクローンしてください。 キャプチャをする流れ SwiftUIそのものにはまだViewからイメージデータに変換するメソッドはありません。 しかしUIKitではImageContex
3 min read
[SwiftUI] GeometryReaderでViewのサイズを知る
iOS

[SwiftUI] GeometryReaderでViewのサイズを知る

Viewサイズをどうやって知る? UIKitではView自身の座標位置やサイズはUIViewのプロパティとしてframeプロパティやboundsプロパティが定義されそれで取得ができました。 SwiftUIのViewには座標位置やサイズを表すプロパティはありません。 ではそれらの情報を取りたいときにはどうすればいいのでしょうか? そのための特別のViewがあります。GeometryReaderです。 GeometryReader GeometryReader は特別なViewで、自身のサイズと座標空間を返す関数をクロージャーとして保持しています。そのクロージャーを通して、自身のViewのサイズや座標位置やRootViewのサイズや座標位置も取得することができます。 GeometryReaderを使うとこんなことができるようになります。 * ScrollViewのスクロールに合わせてコンテンツを操作する * スクロールに合わせてコンテンツのパララックス効果 * ヘッダーをスクロールに合わせて拡大、縮小する * 横スクロールでコンテンツが真ん中に来たら目立たせる
6 min read