ナトーアプリ工房

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

【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

 

 

【Mac】DeepLのショートカットで英文をスピード翻訳する

Macの英文をDeepLのショートカットでスピード翻訳する方法

XcodeSafariからApple Developer Documentationの英文を直ぐに翻訳したい時などに便利な方法です。

  • DeepLをインストール
  • ショートカットキーを変更

□ DeepLをインストールする

aiを使った自然な翻訳が可能なDeepLをインストールします。

www.deepl.com

Macにダウンロード 無料!」をクリックします。

f:id:nato99001:20210605171013p:plain

 

ダウンロードしたファイルDeepL.dmgをダブルクリックしてインストールします。

f:id:nato99001:20210605172846p:plain

 

□DeepLを設定する

Macから「システム環境設定」→「セキュリティとプライバシー」→「プライバシー」タブをクリックします。

鍵を外してアクセシビリティからDeelpLをチェックします。

f:id:nato99001:20210605173754p:plain

 

ログインなしでDeepLを起動します。

ログインの横にある下矢印から環境設定をクリックします。

f:id:nato99001:20210605174123p:plain

 

DeepLのショートカットキーを変更します。

デフォルトは⌘キーCを2回ですが、面倒なので⌘キーLにします。

f:id:nato99001:20210605174407p:plain

 

□ XcodeでDeepLを使ってみる

Xcodeでoptionキーを押しながらクリックするとクイックヘルプが表示されます。

f:id:nato99001:20210605175103p:plain

 

内容が分からない英文をドラックして⌘キーとLをクリックします。

f:id:nato99001:20210605175335p:plain

 

直ぐに翻訳結果が表示されます。

f:id:nato99001:20210605175700p:plain

 

さらに単語を詳しく知りたい時は、単語をダブルクリックします。

f:id:nato99001:20210605180115p:plain

 

赤枠のフィールドをクリックします。

f:id:nato99001:20210605180627p:plain

 

単語の詳細が表示されます。

f:id:nato99001:20210605180728p:plain

 

□ ブラウザでDeepLを使ってみる

Apple Developer Documentation で使ってみます。

developer.apple.com

 

赤枠の英文を翻訳して見ます。

英文をドラックして⌘キーとLをクリックします。

f:id:nato99001:20210605181339p:plain

 

翻訳結果が表示されます。

f:id:nato99001:20210605181642p:plain

 

日本語から中国語など、各種外国語にも対応しています。

f:id:nato99001:20210605182231p:plain

 

【SwiftUI】UdemyLessonサンプルアプリ解説

Udemy SwiftUIオンラインレッスンのサンプルTODOアプリ解説

  • レッスンでの構造体やクラス、変数の名称が抽象的で値の移り変わりが分かりにくいため、日本語名にしました。
  • 全体が見える様、別ファイルを作らないでContentView.swiftに全て記述しました。

アプリの仕様

・+ボタンでテキストフィールドが表示されてTODOを追加

・TODO項目をクリックすると□が☑︎になりTODO内容に取り消し線が入る

・Deleteボタンをクリックするとチェック済みTODOが消える

 

f:id:nato99001:20210529140107p:plain

  • 構造体を配列にする場合idという変数を持った「Identifiableプロトコル」が必要になります。今回はUUIDメソッドにてユニークなidを生成していますが、手動で生成しても大丈夫です。ユニークなidがないとSwiftUIがそのViewで利用されているデータがどれなのかを特定しておかないと、データが更新されたときにどのViewを再構築すればいいのかわからなくなってしまうからです。
  • タップしたリスト行を検知するのにfirstIndex(of:)メソッドを使っています。その場合「Equatabelプロトコル」が必要になります。
  • テキストフィールドで使うプロパティーラッパー@stateを付けた変数に日本語は使えませんでした。

プログラムソースをgithubにアップしています。

github.com

import SwiftUI

 

struct 構造体:Identifiable,Equatable {

    var id = UUID()

    var 構造体check:Bool

    var 構造体todo:String

    init(イニシャライザ変数check:Bool,イニシャライザ変数todo:String) {

        self.構造体check = イニシャライザ変数check

        self.構造体todo = イニシャライザ変数todo

    }

}

 

class クラス:ObservableObject {

    @Published var 構造体インスタンス配列 = [

        構造体(イニシャライザ変数check: true, イニシャライザ変数todo: "勉強"),

        構造体(イニシャライザ変数check: false, イニシャライザ変数todo: "散歩")

    ]

    @Published var 入力状態チェック変数:Bool = false

}

 

struct ContentView: View {

    @EnvironmentObject var クラスインスタンス:クラス

    var body: some View {

        NavigationView {

            List {

                ForEach(クラスインスタンス.構造体インスタンス配列) { ForEach変数 in

                    Button(action:{

                        guard let 要素番号 = クラスインスタンス.構造体インスタンス配列.firstIndex(of: ForEach変数) else {

                            return

                        }

                        self.クラスインスタンス.構造体インスタンス配列[要素番号].構造体check.toggle()

                    })

                    {

                        リスト行表示ビュー(リスト行表示ビュー変数check: ForEach変数.構造体check, リスト行表示ビュー変数todo: ForEach変数.構造体todo)

                    }

                }

                if self.クラスインスタンス.入力状態チェック変数 {

                    行追加表示ビュー()

                } else {

                    Button(action: {

                        self.クラスインスタンス.入力状態チェック変数 = true

                    })

                    {

                        Text("+")

                        .font(.title)

                    }

                }

            }

            .navigationBarTitle(Text("ToDo"))

            .navigationBarItems(trailing: Button(action:{

                削除関数()

            })

            {

                Text("Delete")

            }

            )

        }

    }

    func 削除関数(){

        let 削除関数変数 = クラスインスタンス.構造体インスタンス配列.filter({!$0.構造体check })

        self.クラスインスタンス.構造体インスタンス配列 = 削除関数変数

    }

}

 

struct リスト行表示ビュー: View {

    var リスト行表示ビュー変数check:Bool

    var リスト行表示ビュー変数todo:String

    var body: some View {

        HStack {

            if リスト行表示ビュー変数check {

                Text("☑︎")

                Text(リスト行表示ビュー変数todo)

                    .strikethrough()

                    .fontWeight(.ultraLight)

            } else {

                Text("□")

                Text(リスト行表示ビュー変数todo)

            }

        }

    }

}

 

struct 行追加表示ビュー: View {

    @State var addListViewTodo = "" //現在propertyWrapperでは変数名に日本語を使えません

    @EnvironmentObject var クラスインスタンス: クラス

    var body: some View {

        TextField("タスクを入力してください", text:$addListViewTodo,

        onCommit: {

            self.todo作成関数()

            self.クラスインスタンス.入力状態チェック変数 = false

        })

    }

    func todo作成関数() {

        let 新しいtodo = 構造体(イニシャライザ変数check: false, イニシャライザ変数todo: addListViewTodo)

        self.クラスインスタンス.構造体インスタンス配列.insert(新しいtodo, at: 0)

        self.addListViewTodo = ""

    }

    

}

 

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

            .environmentObject(クラス())

    }

}