- 投稿日:2020-05-22T23:25:16+09:00
Swiftの文について見ていきます
概要
新たにSwiftを学び始めたので、アウトプットも兼ねて、Xcodeの文を見ていきます。
viewController.swiftclass ViewController: UIViewController { @IBOutlet weak var countLabel: UILabel! var count = 0 override func viewDidLoad() { super.viewDidLoad() countLabel.text = "0" } @IBAction func plus(_ sender: Any) { count = count + 1 countLabel.text = String(count) if(count >= 10){ changeTextColor() } } @IBAction func minus(_ sender: Any) { count = count - 1 countLabel.text = String(count) if(count <= 0){ resetColor() } } func changeTextColor(){ countLabel.textColor = .yellow } func resetColor(){ countLabel.textColor = .white } }class ViewController: UIViewController {
@IBOutlet weak var countLabel: UILabel! var count = 0この部分は変数の宣言になります。varとつけて宣言を表明し、その後にcountLabelという変数名をつけています。その後のcount変数を宣言して 0 を代入しています。
override func viewDidLoad() { super.viewDidLoad() countLabel.text = "0" }この部分はアプリを開いた時に自動的に読み込まれる箇所です。
countLabelにオブジェクト.textをつけてそれに文字型の0を代入して表示しています。@IBAction func plus(_ sender: Any) { count = count + 1 countLabel.text = String(count) if(count >= 10){ changeTextColor() } }この部分はボタンがタッチされた時該当する plusメソッドが動きますが、その処理を記述しています。
countに1を足す処理です。そしてさらに足したcountを文字型に変えて表示しています。
その後のif文はcountが10超えたらchageTextColorというメソッドを読み込むという記述です。@IBAction func minus(_ sender: Any) { count = count - 1 countLabel.text = String(count) if(count <= 0){ resetColor() } }ここはさっきと逆でcountから1引く処理をしています。そしてそれを文字型に変えて表示。if文で0以下になったらresetColorというメソッドが読み込まれるという記述です。
func changeTextColor(){ countLabel.textColor = .yellow } func resetColor(){ countLabel.textColor = .white }最後にこの箇所はメソッドを定義する箇所です。
changeTextColorメソッドでは.textColorオブジェクトを使って文字を黄色に変えています。
resetColorメソッドは同じように文字を白色に変えています。
- 投稿日:2020-05-22T21:11:41+09:00
GCDを使ってコールバック地獄をasync/await ライクに回避する
⚠️ 注意 ⚠️
こちらの記事は何かを参考にして書いたというよりもSwift実践入門のGCDの項を読んで自分で編み出した部分が強いので、誤っている可能性があります。
もし強いSwiftエンジニアの方
- ここは間違っている
- もっといいやり方があるよー
などありましたら、コメントで教えていただけると幸いです
いわゆるコールバック地獄
Swiftである非同期処理の結果を別の非同期処理に渡して処理をチェーンさせたい場合、以下のようにコールバックを使うのがよくやるやり方です。
func main() { funcOne { funcOneResult in print(funcOneResult) } } func funcOne(callback: @escaping (_ result: String) -> Void) { let globalQueue = DispatchQueue.global(qos: .userInitiated) globalQueue.async { print("func one called") Thread.sleep(forTimeInterval: 1) callback("funcOneResult") } }上記のように1つなら全然問題ありませんが、2つ、3つとチェーンさせていくと、悪名高いコールバック地獄が発生します。
import Foundation import Dispatch let globalQueue = DispatchQueue.global(qos: .userInitiated) func main() { funcOne { funcOneResult in funcTwo(funcOneResult: funcOneResult) { funcTwoResult in funcThree(funcTwoResult: funcTwoResult) { funcThreeResult in print("result: \(funcThreeResult)") } } } }話は変わってjavascriptではasync/awaitを用いて、このようなコールバック地獄を回避することができます。
イメージこんな感じです。async function main() { const resultOne = await funcOne() const resultTwo = await funcTwo(resultOne) const resultThree = await funcThree(resultThree) console.log(resultThree) }Swiftでもこんな風に実装したいなと思い、紹介するのが今回の方法です。
GCDを使って async/await likeに回避
GCD(Grand Central Dispatch)はC言語ベースのシステムレベルのAPIでキューを通してスレッドの管理を容易にする仕組みで本来は非同期処理に用いるものですが、今回はこちらを同期処理に用います。
ソース全体は以下です。
メソッド呼び出しの箇所のコールバック地獄が取り除かれ、先ほどのjavascriptライクに書けているのが分かります。import Foundation import Dispatch func main() { let queue = DispatchQueue(label: "com.my_company.app", qos: .userInteractive, attributes: [.concurrent]) let funcOneResult = funcOne(queue: queue) let funcTwoResult = funcTwo(funcOneResult: funcOneResult, queue: queue) let funcThreeResult = funcThree(funcTwoResult: funcTwoResult, queue: queue) queue.sync { print("completed, result: \(funcThreeResult)") } } func funcOne(queue: DispatchQueue) -> String { queue.sync { print("func one called") Thread.sleep(forTimeInterval: 1) return "funcOneResult" } } func funcTwo(funcOneResult: String, queue: DispatchQueue) -> String { queue.sync { print("func two called") Thread.sleep(forTimeInterval: 1) return "funcTwoResult" } } func funcThree(funcTwoResult: String, queue: DispatchQueue) -> String { queue.sync { print("func three called") Thread.sleep(forTimeInterval: 1) return "funcThreeResult" } } main()仕組みとしては直列キューを作成して各メソッドの呼び出しの引数として呼び出し、
let queue = DispatchQueue(label: "com.my_company.app", qos: .userInteractive, attributes: [.concurrent]) let funcOneResult = funcOne(queue: queue) let funcTwoResult = funcTwo(funcOneResult: funcOneResult, queue: queue) let funcThreeResult = funcThree(funcTwoResult: funcTwoResult, queue: queue)メソッド内で、そのqueueに対して、syncで処理を呼び出しています。
func funcOne(queue: DispatchQueue) -> String { queue.sync { print("func one called") Thread.sleep(forTimeInterval: 1) return "funcOneResult" } }こうすることで処理が同期的に進行し、以下のような出力となります。
func one called (1秒) func two called (1秒) func three called completed, result: funcThreeResultエラーのハンドリングを行う場合は以下のようになるのではないかなと思います。
func main() { let queue = DispatchQueue(label: "com.my_company.app", qos: .userInteractive, attributes: [.concurrent]) do { let funcOneResult = try funcOne(queue: queue) let funcTwoResult = try funcTwo(funcOneResult: funcOneResult, queue: queue) let funcThreeResult = try funcThree(funcTwoResult: funcTwoResult, queue: queue) queue.sync { print("completed, result: \(funcThreeResult)") } } catch { // handle error print(error) } } extension String: Error {} func funcOne(queue: DispatchQueue) throws -> String { try queue.sync { print("func one called") throw "Some Error" Thread.sleep(forTimeInterval: 1) return "funcOneResult" } }
- 投稿日:2020-05-22T20:27:35+09:00
【iOS】iOSアプリ開発入門~ Swift基礎編1~
前回はボタンタップイベントを受けラベルの色を変更する方法について投稿しました。
SwiftとUIの接続編1:https://qiita.com/euJcIKfcqwnzDui/items/93f010b989a4d333f0b9今回はいくつか簡単な処理を紹介します。
Swiftのコーディング練習がてらこのあたりの処理を入れてもう少しアプリらしくしてみましょう。
それではいつも通りプロジェクトを開いて実装していきましょう。カウントアップさせる処理
ボタンをタップする毎に表示される数字が増えるような処理を紹介します。
デバッグコンソールにカウントアップを表示する
まずカウントアップさせるには今いくつまでカウントされているかという状態を保持しておく必要があります。
この状態を保持するためのスペースをプロパティに準備しておきます。
以下のようにコードを編集します。ViewController.swiftclass ViewController: UIViewController { var count: Int = 0 // < 追加 @IBOutlet weak var label: UILabel! @IBAction func tapButton(_ sender: Any) { self.label.text = "Hello World" self.label.backgroundColor = UIColor.red } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }
count
というプロパティをInt
型で定義しました。
Int
は整数型と呼ばれるものです。数字、特に整数で扱うものはInt型で定義します。一部例外はありますがプログラムでは型を意識する必要があります。
整数ならInt型、少数ならDouble型、文字列ならString型というようにそれぞれ用途に合わせて型を指定してあげなければいけません。
今回の場合はボタンをタップする毎に数字を1ずつ増やすという処理をしたいのでInt型として定義しました。
var count: Int = 0
というように定義していますが、この= 0
いうのは初期化処理です。
つまりcountの初期値は0という値ですよとしてあげています。それではこのcountを使って実装していきます。
tapButton
の処理を以下のように書換えてみます。
書換えたら実行してボタンを何度かタップしてみてください。ViewController.swift@IBAction func tapButton(_ sender: Any) { print("加算前:\(self.count)") self.count = self.count + 1 print("加算後:\(self.count)") print("-----") }デバッグコンソールに以下のように出力されました。
print()関数に関しては以前しました。デバッグコンソールに出力するための処理です。加算前:0 加算後:1 ----- 加算前:1 加算後:2 ----- 加算前:2 加算後:3 -----見ればなんとなくわかるかもしれませんが、ボタンをタップする度に
self.count = self.count + 1
という処理でcount
の値に1を加算しています。ここで出てきた=や+は演算子またはオペレータと呼ばれます。
プログラミングではこの演算子を使い計算をしていきます。「+」はそのままの意味で足し算を行います。
少し注意が必要なのは「=」で、こちらは代入演算子と呼ばれています。
数学上の意味では「=」は等価、つまり左辺と右辺の関係式を表しますがプログラム上では代入を意味します。
少しニュアンスが難しいかも知れませんがここの処理はself.count + 1
の計算結果をself.count
に代入しています。その結果self.count
の値が1加算されたものに書き換わります。
(ちなみに等価の演算子は「==」です)一回目のタップでは代入される前の
self.count
の初期値は0のためprint("加算前:\(self.count)")
では「0」が表示され、加算後self.count
の値は1に書き換わったためprint("加算後:\(self.count)")
では「1」が表示されています。二回目のタップでは
self.count
の値は一回目に1に書換えているためprint("加算前:\(self.count)")
では「1」が表示され、さらに書き換えを行い2に更新しています。試しに代入を行わず以下のような処理にしてみましょう。
ViewController.swift@IBAction func tapButton(_ sender: Any) { print("加算前:\(self.count)") print("加算後:\(self.count + 1)") print("-----") }以下のように出力されました。
加算前:0 加算後:1 ----- 加算前:0 加算後:1 ----- 加算前:0 加算後:1 -----これは
self.count
に代入を行っていないため初期値の0のままになっているためです。
self.count + 1
の計算はprint("加算後:\(self.count + 1)")
で1と表示されているので正しく行われていますが、self.count
が更新されないため同じ結果が常に表示されています。
値を更新したい場合は必ず代入するようにしてください。このようにして値を更新、保持しながらアプリの状態を制御していきます。
カウントアップ結果をラベルに表示する
print()関数だけではアプリの表示は変更されないので
self.count
を表示してみましょう。
これまでの内容を理解できていれば特に難しいことはなく、ラベルの表示変更とカウントアップの処理を組み合わせるだけです。コードを以下の様に書き換え実行してみましょう。
ViewController.swift@IBAction func tapButton(_ sender: Any) { self.count = self.count + 1 self.label.text = "カウント:\(self.count)" } override func viewDidLoad() { super.viewDidLoad() self.label.text = "カウント:\(self.count)" }ラベルの表示が「カウント:0」から始まり、ボタンをタップする毎にカウントが増えていきました。
基本的には前項の処理とは変わらずself.count = self.count + 1
で1ずつ加算していき、その値をラベルに表示しているだけです。処理をもう少し詳しく見ててみましょう。
まず
tapButton
内の処理について。
先程と同様にself.count = self.count + 1
でself.count
が更新されていますね。
更新した結果をself.label.text = "カウント:\(self.count)"
に代入しています。
そのためラベルには加算された値が表示されています。
ラベルの更新の際self.count
が\()
で囲まれています。
冒頭で言いましたがプログラムでは型を意識する必要があります。
UILabelのtextの定義を見てみます。(見方は前回説明しました)
open var text: String?
というように定義されています。
「?」はひとまず気にせず、String
型つまり文字列型で定義されており、count
はInt
型なので型が異なるということがわかります。
プログラムでは型が異なる場合は直接代入できないという決まりがあります。
そこでInt
をString
に変換してあげる必要があります。
型を変換する処理のことをキャストと呼び、\()
はInt
をString
にキャストするための処理です。
キャストしてあげた結果"カウント:\(self.count)"
はString
型に変換されtext
に代入できるようになりました。次は
viewDidLoad
の処理について。
tapButton
の処理では更新した値を表示していますが、1を加算した値を表示しているため初期値の0が表示されることはありません。
そもそもtapButton
はボタンをタップするというイベントを起こして初めて動く処理のため、画面を表示した瞬間のラベルの表示を制御できません。
ですがアプリを実行したときは「カウント:0」と表示されていました。
これを実現するための処理がviewDidLoad
の内容です。
このviewDidLoad
はプロジェクトを作成した段階ですでに定義されていましたが、何をするための処理なんでしょう?
今回は詳しく説明しませんがアプリの画面、つまりViewControllerにはライフサイクルというものがあり、「画面が表示された」、「画面が非表示」になったなど、画面の表示状態などによって勝手に呼ばれるメソッドが元々定義されています。
viewDidLoad
もライフサイクルの1つで「画面がメモリ上に確保された」タイミングで呼ばれます。
基本的にこのタイミングで画面の初期化処理を行います。
初期化処理としてself.label.text = "カウント:\(self.count)"
を行ったため画面が表示された瞬間「カウント:0」と表示されていたというわけです。カウント毎にテキストの色を変える
もう少し遊んでみましょう。
先程等価式は「==」の演算子を使うと少し話しましたがこの等価演算子を使ってみます。プログラムには条件判定を行うためにif文を呼ばれるものが用意されています。EXCELなどにもありますがそれと同じです。
「if文」を使えば特定の条件の場合のみ行う処理を記述することができます。コードを以下の様に書き換え実行してみましょう。
ViewController.swift@IBAction func tapButton(_ sender: Any) { self.count = self.count + 1 self.label.text = "カウント:\(self.count)" let remainder: Int = self.count % 2 if remainder == 0 { self.label.textColor = UIColor.red } else { self.label.textColor = UIColor.blue } } override func viewDidLoad() { super.viewDidLoad() self.label.textColor = UIColor.red self.label.text = "カウント:\(self.count)" }タップする度に文字色が赤→青→...と変わります。
viewDidLoad
で文字色の初期値を赤に指定していますね。
tapButton
に注目してください。
let remainder = self.count % 2
とあります。
まず「%」は余りを求める演算子です。self.count % 2
はself.count
を2で割った余りを結果として返します。
つまり偶数の場合は0、奇数の場合は1となり、remainder
には0 ro 1が代入されます。
remainder == 0
ではremainderと0が等価かどうかを計算しています。
このように「==」など左右の値の関係を比較する演算子を比較演算子と呼びます。
比較演算子は他に「>」,「>=」,「<」,「<=」があります。これらの意味は数学と同じで大なり、大なりイコールといった意味になります。
比較演算子の計算結果はInt
型ではなくBool
型となります。Bool
型は論理型と呼ばれ真偽値、つまりtrue/falseを格納します。
今回の場合0と比較しているのでremainder
が0ならtrue、1ならfalseの値が返されます。
試しにprint(remainder == 0)
とするとtrue or falseが表示されます。「if文」では真偽値を判定します。
構文としては以下の様になります。if 真偽値 { trueの場合の処理 } else { falseの場合の処理 }従って
count
が偶数の場合は文字色が赤となり、奇数の場合は文字色が青となったというわけです。余談ですがif文は以下のような感じでelseなしやさらにif文で繋げることもできます。
// else なし if self.count % 2 == 0 { // countが「2n」の場合の処理 } // if文を繋げる if self.count % 3 == 0 { // countが「3n」の場合の処理 } else if self.count % 3 == 1 { // countが「3n+1」の場合の処理 } else { // 上記判定に当てはまらなかった場合の処理 }最後に
今回はカウントアップや条件分岐など少しプログラミング的な処理を入れてUIを更新してみました。
もちろんこれは簡単な例でさらに複雑な処理を与えてあげればもっと細かい制御ができるようになります。今回紹介した内容は簡単ではありますが全てのプログラミングに共通する考え方で非常に重要な内容です。
もし理解できなかった場合は読み直しさらに練習するなどで自分のものにしてください。特にif文は非常に重要で、他に繰り返しを制御するfor文というものがありますが
if文とfor文があれば全ての処理を記述できると言われています。
しっかりと理解できるようにしましょう。for文という単語を出したので次回はfor文を使ってUIを更新してみたいと思います。
本連載ではプログラミング未経験からiOSアプリ開発が行えるようになることを目的としています。
今までの投稿をまとめていますのでこちらもご覧ください。
アジェンダ:https://qiita.com/euJcIKfcqwnzDui/items/0b480e96166e88945684
- 投稿日:2020-05-22T09:12:58+09:00
【swift】singleton(シングルトン)とその代替案について
はじめに
今回は、シングルトンについて書いていこうと思います!
シングルトンとはなんぞやと言うところから、シングルトンを使う場面やメリットについて公式ドキュメントを元に書いていきます!公式doc:Managing a Shared Resource Using a Singleton
共有リソースの管理者:シングルトン
公式ドキュメントのタイトルにある通り、シングルトンは共有リソースにアクセスします。
ざっくり言えば、インスタンス内の値を変更後、別のインスタンスを生成しても前者のインスタンスの更新内容が反映されるどういった処理が可能になります。つまり、インスタンスが1個しか生成されないことを保証します。
イメージとしては、こちらの記事がとても参考になるので一読をお勧めします!
シングルトンについて swiftまず、コードでみていきます!
class single { var name = "singletonのお勉強" static let singleton = single() //staticキーワードでsingle()をsingletonに代入 private init(){} } var test = single.singleton //最初のインスタンス print(test.name) //出力:singletonのお勉強 test.name = "singleton実装" let singleton = single.singleton //値更新後のインスタンス print(singleton.name) //出力:singleton実装見ての通り、
static let singleton = single()
の部分でsingleton
を作ります。
そうすることで、複数のスレッドで同時アクセスされた場合でも、1回だけ遅延して初期化されることが保証されます。また、初期化以外の設定を実行する必要がある場合は、以下のようにクロージャーを用いることもあります。
class singleton{ static let sharedInstance: singleton = { let instance = singleton() //追加設定処理 return instance }() }シングルトンの使う場面
この機能についてはおおよそわかったが、では一体どのような場面でシングルトンを使うのだろうか、、
Swift におけるシングルトン・staticメソッドとの付き合い方
こちらの記事によると、
delegate
にシングルトンインスタンスしか渡せない場合- インスタンスメソッド実装が必要な既存のプロトコルに準拠させたい場合
- その他、大体の場合
static
プロパティ・メソッドを束ねたstructで代用できるえ、
singleton
使う場面、めっちゃ少ないやんこの記事の筆者曰く、swiftの場合、
singleton
の実装が簡単なので必要なくても使ってもいいのではと。シングルトンは大抵、
static
プロパティ・メソッドを束ねたstructで代用できる実際にコードで見ていきます
struct MyStruct{ private init(){} static var value = "original" static func foo() { print("foo") } } var myStruct = MyStruct.self myStruct.foo() myStruct.value = "シングルトンもどき" print(myStruct.value) // シングルトンもどき print(MyStruct.value) // シングルトンもどき確かに、、シングルトンと同じだ、、
- 投稿日:2020-05-22T06:36:10+09:00
Core Data を使用する既存のアプリに CloudKit 機能を追加
Core Data
テクノロジーを使用するアプリをお持ちの場合は、CloudKit
サポートを簡単に追加できます。
CloudKit
を利用すれば、データベースに保存されたデータをユーザーのデバイス間で同期させることができます。
CoreData + CloudKit
機能は、デフォルトで、ユーザーの情報をプライベートデータベースに保存します。つまり、ユーザーが他のデバイス上で同じApple IDを使ってサインインした場合にのみ保存されたユーザーの情報にアクセスできます。ステップ 1. Xcodeプロジェクト設定で必要な機能をオンにする。“iCloud”の"CloudKit”をオンにする。
「CloudKit」をオンにします
既存の"Containers"のトグルボタンをどれかひとつクリックするか、プラスアイコンをクリックして新規"Container"を加える。
新規"Container"を加える:
追加ボタンをクリックします
新しい「Container」の名前を入力してください
ステップ 2.
Core Data
の設定でCloudKit
サポートをオンにしますデータベースモデルを変更
- まず、
. xcdatamodeld
ファイルを開きますConfiguration
タブで構成を選択します:
- 画面の右側で、クリックし、
CloudKit
で使用をオンにします (Used with CloudKit)コード内のクラウドコンテナにアクセスする
そして、すべての
NSPersistentContainer
をNSPersistentCloudKitContainer
に置き換えます。AppDelegate.swift
ファイルに1つある可能性があります。元の:
let container = NSPersistentContainer(name: "CoreDataDemo")新:
let container = NSPersistentCloudKitContainer(name: "CoreDataDemo")ステップ 3. テストとデプロイ
クラウドデータベースを設定する必要がないことに注意してください。データベース構造は自動的に
CloudKit
の開発サーバーにデプロイされます。次に、しばらくの間アプリを使用し、Core Data
データが生成されていることを確認する必要があります。このステップは重要です!次に
CloudKit
のオンラインポータル http://icloud.developer.apple.com へ行き、あなたのアプリを左側から見つけて、開発データベースをプロダクションにデプロイします。これを忘れると、App Storeからあなたのアプリをダウンロードした実際のユーザーが、データをクラウドに同期できなくなります。最後にはiCloudの開発用データベースを本番環境にデプロイする必要があります。
- 投稿日:2020-05-22T01:01:44+09:00
【SwiftUI】基本的なモディファイアの種類と使い方①
bodyプロパティ
定義:var body: Self.Body
ContentViewではカスタムビューの内容を記述する
複数のViewを組み合わせるにはVStackなどを使用してひとつにまとめる必要がある。frameモディファイア
フレームのサイズとビューの配置位置を指定
func frame(width: ,height: , alignment: ,) alignmentの種類 center,leading,trailing,top,bottom,topLeading,topTrailing,bottomLeading,bottomTrailing func frame(minWidth: ,idealWidth: ,maxWidth…..)cssでいうwidth,height,
fixedSizeモディファイア
ビューの表示を固定
func fixedSize() -> some View func fixedSize(horizontal:Bool,vertical:Bool) -> some View horizontal 横方向のはみ出しを許すか vertical 縦方向のはみ出しを許すかborderモディファイア
境界線を表示
func border(content:境界線のスタイル ,width:線の太さ ) contentにはColor,ImagePaint,LinearGradient,RadialGradientなどが入るcssでいうborder
positionモディファイア
ビューの中心を親の座標空間の指定された座標に配置
func position(x: .y: ) -> some Viewpositionを指定するとそれまでのframeの設定がリセットされる、フレームサイズは強制的に親ビューと同じになる。フレームサイズを指定してその中に座標系を作りたい時はpositionの後にframeモディファイアを指定。
cssでいうtop,bottom,left,rightoffsetモディファイア
元の位置を基準としてビューの表示位置をずらす
func offset(x:横方向へずらす距離, y:縦方向にずらす距離)cssでいうmargin
edgesIgnoringSafeAreaモディファイア
指定された辺に対して、ビューの配置可能領域をセーフエリアの外へ拡張
func edgeIgnoringSafeArea(_ edges: Edge.Set) -> some View 引数edgesの種類(top,bottom,leading,trailing,horizontal,vertical,all) 例 .edgesIgnoringSafeArea(.vertical)paddingモディファイア
ビューの周りの余白を追加
cssと同じfunc padding(_ length: CGFloat) -> some View 引数にはtop,leading,bottom,trailingを指定できる 例 .padding(.init(top:10,bottom:30,trailing:50))backgroundモディファイア
背景設定
例.background(Image("aaa_image")) .background(Color.yellow)cssと同じ
foregroundColorモディファイア
ビューの前景要素に使う色を設定
テキストビューの場合文字色の指定
cssのcolorと同じ?
例.foregroundColor(Color.yellow)overlayモディファイア
ビューの前に別のビューを重ねて配置
重ねるビューのサイズは元のビューサイズに制限される
画像にキャプションを付けることも可能
例Image("logo-image") .overlay( Text("hello") font(.largeTitle) .foregroundColor(.white) .padding(), alignment: .top)*要素のサイズがフレームに収まりきらないときに切り捨てられるのはテキストビュー特有の動作
clippedモディファイア
ビューをフレームの境界で切り取る
定義func clipped(animated: Bool) -> some View
例Image("aaa_image") .frame(width:100,height:100) .clipped()clipShapeモディファイア
ビューの切り取り形状を指定
シェイプの種類
Capsule-カプセル状
Circle-円
Ellipse-楕円
Path-任意のパス
Rectangle-四角形
RoundedRectangle-角丸四角形
例Image("aaa_image") .clipShape(Circle())maskモディファイア
引数のビューを使ってマスクする
例Image("haikei_image") .mask(Image("temae_image")) ビューを透過させることも出来る .mask(Color(red:0.0,blue:0.0,green:0.0,opacity:0.5))cornerRadiusモディファイア
指定されたコーナーの半径でビューを角丸にクリップ
cssのborder-radiusと同じ
例Image("aaa_image") .cornerRadius(10)