ナトーアプリ工房

iOS開発やApple製品の情報発信ブログです

【SwiftUI】@EnvironmentObject

@EnvironmentObject

@EnvironmentObjectは@ObservedObjectをそれぞれのViewで共通のプロパティを使えるようにしたものです。

 

インスタンスの基となるクラスは『ObservableObjectプロトコルを付けます

 

②Viewを更新したいプロパティには@Publishedを付けます

 

インスタンスを作成する際は@EnvironmentObjectを記述します

 ※型を指定しているだけなので、クラス名の後には『()』は付けません

 

【複数のViewに更新されない例】

 

mport SwiftUI

 

struct ContentView: View {

    @ObservedObject var フルーツ = クラス(果物:"🍎", 数:1)

    var body: some View {

        VStack {

            Button(action: 関数1, label: {

                Text("果物を変える")

            })

            Button(action: 関数2, label: {

                Text("個数を変える")

            })

            Text("ContentView \(フルーツ.果物)\(フルーツ.)個買いました")

            ContentView2()

        }

    }

    func 関数1() {

        switch フルーツ.果物{

        case "🍎":

            フルーツ.果物 = "🍌"

        default:

            フルーツ.果物 = "🍎"

        }

    }

    func 関数2() {

        フルーツ. = フルーツ. + 1

        }

}

class クラス: ObservableObject {

    @Published var 果物 :String

    @Published var :Int

    init(果物:String, 数:Int) {

        self.果物 = 果物

        self. = 数

    }

}

struct ContentView2: View {

    @ObservedObject var フルーツ = クラス(果物:"🍎", 数:1)

    var body: some View {

        Text("ContentView2 \(フルーツ.果物)\(フルーツ.)個買いました")

    }

}

 

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

    }

}

 

【ボタンをクリックしてもContentView2は更新されない】

 

【複数のViewに更新する例】

import SwiftUI

 

struct ContentView: View {

    @EnvironmentObject var フルーツ:クラス

    var body: some View {

        VStack {

            Button(action: 関数1, label: {

                Text("果物を変える")

            })

            Button(action: 関数2, label: {

                Text("個数を変える")

            })

            Text("ContentView \(フルーツ.果物)\(フルーツ.)個買いました")

            ContentView2()

        }

    }

    func 関数1() {

        switch フルーツ.果物{

        case "🍎":

            フルーツ.果物 = "🍌"

        default:

            フルーツ.果物 = "🍎"

        }

    }

    func 関数2() {

        フルーツ. = フルーツ. + 1

        }

}

class クラス: ObservableObject {

    @Published var 果物 = "🍎"

    @Published var = 1

}

struct ContentView2: View {

    @EnvironmentObject var フルーツ:クラス

    var body: some View {

        Text("ContentView2 \(フルーツ.果物)\(フルーツ.)個買いました")

    }

}

 

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

            .environmentObject(クラス())

    }

}

 

【ボタンをクリックするとContentView2も更新される】

 

【SwiftUI】@ObservedObject

@ObservedObject

インスタンスでViewを更新したい場合は@Stateでは無く@ObservedObjectを使います

@ObservedObjectが付いたインスタンスのプロパティが変更された時にViewを更新します

 

インスタンスの元となるクラスには ObservableObject プロトコルを付けます

インスタンスを作成する際に@ObservedObjectを付けます

③Viewを更新したいプロパティには@Publishedを付けます

 

【Viewが更新されない例】

import SwiftUI

 

struct ContentView: View {

    var フルーツ = クラス(果物:"🍎", 数:1)

    var body: some View {

        VStack {

            Button(action: 関数1, label: {

                Text("果物を変える")

            })

            Button(action: 関数2, label: {

                Text("個数を変える")

            })

            Text("\(フルーツ.果物)\(フルーツ.)個買いました")

        }

        

    }

    func 関数1() {

        switch フルーツ.果物{

        case "🍎":

            フルーツ.果物 = "🍌"

        default:

            フルーツ.果物 = "🍎"

        }

    }

    func 関数2() {

        フルーツ. = フルーツ. + 1

        }

}   

class クラス {

    var 果物 :String

    var :Int

    init(果物:String, 数:Int) {

        self.果物 = 果物

        self. = 数

    }

}

 

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

    }

 

ボタンをクリックしてもViewが更新されません

 

【Viewを更新させる例】

import SwiftUI

 

struct ContentView: View {

    @ObservedObject var フルーツ = クラス(果物:"🍎", 数:1)

    var body: some View {

        VStack {

            Button(action: 関数1, label: {

                Text("果物を変える")

            })

            Button(action: 関数2, label: {

                Text("個数を変える")

            })

            Text("\(フルーツ.果物)\(フルーツ.)個買いました")

        }

        

    }

    func 関数1() {

        switch フルーツ.果物{

        case "🍎":

            フルーツ.果物 = "🍌"

        default:

            フルーツ.果物 = "🍎"

        }

    }

    func 関数2() {

        フルーツ. = フルーツ. + 1

        }

}

class クラス: ObservableObject {

    @Published var 果物 :String

    @Published var :Int

    init(果物:String, 数:Int) {

        self.果物 = 果物

        self. = 数

    }

}

 

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

    }

 

ボタンをクリックするとviewが更新されます

 

 

【Xcode】iOSアプリにボタンの長押しを実装する方法

iOS アプリでボタンの長押しを判定して処理を実装する方法です。

プラスボタンでオブジェクトライブラリーを表示させ「Long Press Gesture Recognizer」を選択。

長押しを実装したいボタンにドラッグ&ドロップ。

f:id:nato99001:20220130215456p:plain

 

すでに「壱万円」と「五千円」のボタンには長押しを実装しているので、3番目が「弐千円」の「「Long Press Gesture Recognizer」になります。

f:id:nato99001:20220130215846p:plain

 

「Long Press Gesture Recognizer」のアイコンを右クリックしてViewController.swiftへドラッグ&ドロップします。

f:id:nato99001:20220130220405p:plain

 

Typeを「UILong Press Gesture Recognizer」にして「Connect」をクリックします。

f:id:nato99001:20220130220600p:plain

ロングタップ中は何もしなく、タップの指が離れたときに処理を実装する場合「.began」には何も記述しないで「.ended」に記述します。

if sender.state == .began {

        } else if sender.state == .ended {

 

f:id:nato99001:20220130220926p:plain



 

【Xcode】iOSアプリ実機テストで「The operation couldn’t be completed. Unable to log in with account 〜」のエラーを回避する方法

Xcodeの実機テストで下記のエラーが出たときの回避方法です。

Showing Recent Messages
The operation couldn’t be completed. Unable to log in with account '自分のメールアドレス'. The login details for account '自分のメールアドレス' were rejected.

 

Showing Recent Messages
No signing certificate "iOS Development" found: No "iOS Development" signing certificate matching team ID "自分のID" with a private key was found.

 

Xcode → Preference Accounts の画面から「Sign in Again..」をクリックします

f:id:nato99001:20220116112109j:plain

 

Apple ID のパスワードを入力して「Next」をクリックします

f:id:nato99001:20220116112437j:plain

 

エラーが消えました。

f:id:nato99001:20220116113008j:plain

 

 

 

【Xcode】iOSアプリ実機テストで「Unable to install "アプリ名"」のエラーを回避する方法

Macが古く、MacOSXcodeのバージョンアップが頭打ちの状態でiPhoneを最新のバージョンにしてしまったら実機のデバックでサポート外エラーが出てしまう事があります。

一つ前の記事の「Device Support のダウンロード」をするとArchiveは出来ても、実機テストで「Unable to install "アプリ名"」のエラーが出る場合の解決方法になります。

f:id:nato99001:20220102214614p:plain

「Detales」をクリックすると「The code signature version is no longer supported」の表示があります。

f:id:nato99001:20220102215110p:plain

1.codesignの呼び出しに--generate-entitlement-derフラグを追加

「Other Code Signing Flags」の「▶︎」をクリックします。

f:id:nato99001:20220102215915p:plain

「Debug」の「+」をクリックします。

f:id:nato99001:20220102220151p:plain

「--generate-entitlement-der」と入力します。

f:id:nato99001:20220102220435p:plain

 

以上で実機テストが出来るようになります。

起動するまでの時間が長くなる事がありますが根気よく待ちましょう。

 

参考になった記事

stackoverflow.com



 

 

 

【Xcode】iOSのバージョンを最新にしてXcodeのバージョンは古いままで実機デバックする方法

Macが古く、MacOSXcodeのバージョンアップが頭打ちの状態でiPhoneを最新のバージョンにしてしまったら実機のデバックでサポート外エラーが出てしまう事があります。

 

Macを買い換えるという手もありますが、ちょっとした手順で古いMacのままでも実機デバックが可能ですのでお悩みの方は一度お試しください。

1.Device Support のダウンロード

以下のGitHubリポジトリにアクセスして、実機iOSバージョンのデバイスサポートをダウンロードします。

github.com

 

ダウンロードしたいiOSの「Download」ボタンをクリックします。

f:id:nato99001:20211231171635p:plain

ダウンロードフォルダに保存されます。

f:id:nato99001:20211231191228p:plain

 

2. Device SupportフォルダをXcodeディレクトリに置く

ダウンロードフォルダに保存されているデバイスサポートのフォルダを以下のフォルダに移動させます。

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/

①ファインダーから「アプリケーション」→「Xcode」を右クリックして「パッケージの内容を表示」をクリックします。

f:id:nato99001:20211231195942p:plain

②「Contents」を開きます。

f:id:nato99001:20211231200158p:plain

③「Developer」を開きます。

f:id:nato99001:20211231200345p:plain

④「Pratforms」を開きます。

f:id:nato99001:20211231200556p:plain

⑤「iPhoneOS.platform」を開きます。

f:id:nato99001:20211231200814p:plain

⑥「DeviceSupport」を開きます。

f:id:nato99001:20211231200942p:plain

⑦ダウンロードしたデバイスサポートのフォルダを移動させます。

f:id:nato99001:20211231202026p:plain

 

パスワードを入力して「OK」をクリックします。

f:id:nato99001:20211231202009p:plain

 

 

 

 



 

 

 

 

 





 

 

 

【Xcode】カスタムカラーを作成する

Xcodeでカスタムカラーを作成する方法

  • Assets.xcassetsの+ボタンを選択する
  • Color Setを選択する
  • inspecters - Attributes のカラーを調整する
  • 複数カラーを作成する場合はFolderを作成すると便利

f:id:nato99001:20210612205002j:plain

 

f:id:nato99001:20210612210102p:plain