9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Apple Watch開発コトハジメまとめ:ボタンを押すと「にゃあ」という猫 on Apple Watch

Last updated at Posted at 2020-01-25

この記事でできるもの

ボタンを押すと「にゃあ」という猫 on Apple Watch

Youtube動画↓
ねこの動画

GitHub

Step1. Hello, Watch!

  1. Apple Watchアップデート

    • まずはOSアップデートから
    • これしないとインストールできませんでした
    • iOSからできなかったのでWatch本体の設定からインストールしました
  2. アプリのbuild & install

    • Hello World 簡単なWatchアプリ作成 がわかりやすかったです
    • Watchアプリをインストールするときはビルド対象をWatchKit Appにします
      • image.png
    • 以下が出るときはXcode再起動
      • Another launch session is already waiting to debug the app extension with

Step2. SwiftUIの勉強

  1. SwiftUI Tutorial

    • watchOSもSwift。まずはSwiftの書き方から
    • 動画もあるみたいですが、僕はWebページの方見ながらやりました
  2. SwiftUI Tutorialの4わかりづらく下記に進みました

Step3. 猫の画像をApple Watchに貼る

  1. SwiftUI - Circular Image Example.には画像のサイズ調整までできるいい感じのコードがありました

    • Image("neko")でneko.jpgを表示します
  2. WatchKit ExtentionのAssets.xcasset以下にneko.jpgをドラッグアンドドロップ

    • image.png
  3. 表示されました

    • image.png

Step4. 画像をボタンにする

1. SwiftUIでボタンを作成


VStack {
    Button(action: {
        
        self.buttonState.toggle()

    }) {
        Text("Button")
            .font(.headline)
    }

    if buttonState {
        Text("unnyyyyyyaaaaa")
            .font(.headline)
    }
}

2. 画像をボタンにする

  • stackoverflowにあるように下記のように設定したら動くようになりました
    • オリジナルの画像をレンダリングするようにしないといけないみたいです
Image("neko").renderingMode(.original)

3. 画像ボタンのコード


VStack {
    Button(action: {
        
        self.buttonState.toggle()
        
    }) {
        VStack {
            Image("neko")
            .renderingMode(.original)
            .resizable()
            .frame(width: 100, height: 100)
            .clipShape(Circle())
            .overlay(
                Circle().stroke(Color.gray, lineWidth: 4))
                .shadow(radius: 10)
        }
    }

    if buttonState {
        Text("unnyyyyyyaaaaa")
            .font(.headline)
    }
}

4. ボタンを押すとテキストが変わります

image.png

Step5. ボタンを押すと「にゃあ」というようにする

ObservedObjectとは
~省略~

実装したクラスやモデルが持つプロパティを監視する
監視しているプロパティが更新されると変更が通知される
ObservableObjectを適用したクラスの一部実装にPublished属性を利用することができる

  • @Stateは変数、@ObservedObjectはクラスの変更を非同期にやってくれる、みたいな感じみたいです
  1. 再生する音源を用意します。今回は適当に拾ってきたcat.mp3

image.png

  1. Xcodeに必要な設定をします
  • Link Binary With LibrariesにAVFoundation.frameworkを追加
  • Copy Bundle Resourcesにcat.mp3を追加
    • image.png

1. 音の再生を管理するclassを作成します

SoundPlayModel.swift

import Foundation
import AVFoundation

class SoundPlayModel: ObservableObject {
    var audioPlayer = AVAudioPlayer()

    init() {
        let sound = Bundle.main.path(forResource: "cat", ofType: "mp3")
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: sound!))
        }
        catch {
            print(error)
        }
    }
    
    func play() {
        self.audioPlayer.play()
    }
}

2. ControllerからContentViewに渡します

HostingController.swift

class HostingController: WKHostingController<ContentView> {
    
    override var body: ContentView {
        return ContentView(soundPlayModel: SoundPlayModel())
    }

3. ObservedObjectでSoundPlayModelを宣言して受け取ります

ContentView.swift

struct ContentView: View {
    @ObservedObject var soundPlayModel: SoundPlayModel

# ~省略~ 

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(soundPlayModel: SoundPlayModel())
    }
}

4. 最終的なコード

ContentView.swift

import SwiftUI
import Combine
import AVFoundation

struct ContentView: View {
    @ObservedObject var soundPlayModel: SoundPlayModel
    @State private var buttonState = false

    var body: some View {
        
        VStack {
            Button(action: {
                
                self.buttonState.toggle()
                
                if self.buttonState {
                    self.soundPlayModel.play()
                }
                
            }) {
                VStack {
                    Image("neko")
                    .renderingMode(.original)
                    .resizable()
                    .frame(width: 100, height: 100)
                    .clipShape(Circle())
                    .overlay(
                        Circle().stroke(Color.gray, lineWidth: 4))
                        .shadow(radius: 10)
                }
            }

            if buttonState {
                Text("uunnyyyyyyaaaaa")
                    .font(.headline)
            }
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(soundPlayModel: SoundPlayModel())
    }
}

5. 完成!

Youtube動画↓
ねこの動画

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?