Swiftでできる機能の一部をまとめたよ

# はじめに
この記事はswiftを使って簡単に実装できる機能の一部を抜粋してまとめたものになります。
私はモーションセンサーとかビビるほど簡単に実装できて、swiftすげーってりました。
swiftって色々できて面白いね！

今回は以下の機能について簡単に説明してます
- アニメーション
- 音声の再生
- ウェブサイトの表示
- 地図
- イメージフィルタ
- モーションセンサー

# アニメーション
完成イメージ
ボタンを押したらちいかわが動く

![スクリーンショット 2023-06-20 23.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/1c2cee54-4fe5-0a2c-9d63-19765f2be73a.png)


ex). ボタンを押下時に、画像が動くアニメーションを実装する

Main.storyboardにボタンとImage Viewをよしなに配置する

``` ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func buttonTapped(sender: UIButton) {        
        UIView.animate(withDuration: 1.0, delay: 0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0.1, options: .curveLinear, animations: {
            self.imageView.transform = CGAffineTransform(translationX: 0, y: 100)
        }) {(true) in
            UIView.animate(withDuration: 1.0, animations: {
                self.imageView.transform = CGAffineTransform.identity
            })
        }
    }
```

これでボタンが押された際に1秒でy座標(上下)側に100だけ移動するアニメーションができる。

``` swift
UIView.animate(withDuration: 1.0, delay: 0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0.1, options: .curveLinear, animations: {
            self.imageView.transform = CGAffineTransform(translationX: 0, y: 100)
        })
```
ここで書いてることについて詳細に説明する
``` swift
withDuration: 1.0 // 何秒のアニメーションか
delay: 0 // このアニメーションが起動するまで何秒遅延があるか
usingSpringWithDamping: 0.1 // バネ係数(今回はバネのような動きを実装しているため)
initialSpringVelocity: 0.1 // 初速(今回はバネのような動きを実装しているため)
options: .curveLinear // 直線的にバネの移動をさせる(今回はバネのような動きを実装しているため)
```

``` swift
{(true) in
            UIView.animate(withDuration: 1.0, animations: {
                self.imageView.transform = CGAffineTransform.identity
            }
```
上のコードでアニメーションが終わると、1.0秒で元の位置に戻る処理を記述している。

# 音声の再生

完成イメージ
ボタンを押したら音声が鳴る
![スクリーンショット 2023-06-20 23.38.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/0c1a259e-53e8-ef96-f6e2-d98c9cf6db9f.png)


ex). ボタン押下時に音声を再生する実装を行う

Main.storyboardにボタンとImage Viewをよしなに配置する

``` ViewController.swift
import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate {
    
    var player: AVAudioPlayer!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func buttonTapped(sender: UIButton) {
        let url = URL(fileURLWithPath: Bundle.main.bundlePath).appendingPathComponent("sample.mp3")
        do {
            player =  try AVAudioPlayer(contentsOf: url)
            player.delegate = self
            player.play()
        } catch {
            print("Failed!")
        }
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Finished!")
    }
    
}
```

ここで書いてることについて詳細に説明する

``` swift
@IBAction func buttonTapped(sender: UIButton) {
        let url = URL(fileURLWithPath: Bundle.main.bundlePath).appendingPathComponent("sample.mp3")
        do {
            player =  try AVAudioPlayer(contentsOf: url) // 音声ファイルのあるurlを指定する
            player.delegate = self
            player.play() // 音声を再生する
        } catch {
            print("Failed!")
        }
    }
```

``` swift
// 音声再生終了時にコンソールに"Finished!"と記述する
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Finished!")
    }
```

# ウェブサイトの表示

完成イメージ

![スクリーンショット 2023-06-20 23.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/42dd0720-aea1-c4d9-a5e9-51543c5bbf7b.png)


Main.storyboardにWeb View、Tool bar(リロードボタン、戻るボタン、進むボタン)をよしなに配置する

``` ViewController.swift
import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    @IBOutlet var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        if let url = URL(string: "http://www.google.com") {
            let request = URLRequest(url: url) // 表示したいページのURLを指定
            webView.load(request) // 表示しいたいページをロード
        }
        webView.navigationDelegate = self
    }

    @IBAction func reloadTapped(sender: UIButton) {
        webView.reload() // リロードボタンをタップ時にリロードする
    }
    
    @IBAction func backTapped(sender: UIButton) {
        webView.goBack() // バックボタンタップ時にひとつ戻る処理
    }
    
    @IBAction func forwardTapped(sender: UIButton) {
        webView.goForward() // 進むボタンタップ時にひとつ進む処理
    }
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("Start!") // viewが読み込み始めた時にコンソールに出力
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Finish!")　viewが立ち上がったときにコンソールに出力
    }
}
```

# 地図

完成イメージ

standard
![スクリーンショット 2023-06-20 23.19.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/e672ab3a-4cae-0166-2e9f-3c92133dc536.png)

satellite

![スクリーンショット 2023-06-20 23.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/6c0e66d2-c1b6-db18-359a-87bad3847928.png)



Main.storyboardにMap Kit View、Segment Controll(standard, satellite, hybrid)をよしなに配置する

``` ViewController.swift
import UIKit
import MapKit

class ViewController: UIViewController {
    
    @IBOutlet var mapView: MKMapView!
    @IBOutlet var segmentControl: UISegmentedControl!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        var region = MKCoordinateRegion() // mapのインスタンス化
        region.center = CLLocationCoordinate2DMake(35.658611, 139.745556) // mapの中心座標を決定
        region.span.latitudeDelta = 0.02 // 中心からどのくらいの緯度を表示するか
        region.span.longitudeDelta = 0.02　// 中心からどのくらいの経度を表示するか
        mapView.setRegion(region, animated: false) // mapViewに上で定義したmapをセット
        
        mapView.mapType = .standard // mapタイプを指定
    }

    // mapタイプを指定
    @IBAction func segmentChanged(sender: UISegmentedControl) {
        switch sender.selectedSegmentIndex {
        case 0:
            mapView.mapType = .standard
        case 1:
            mapView.mapType = .satellite
        default:
            mapView.mapType = .hybrid
        }
    }

}
```

# イメージフィルタ

完成イメージ
元の画像よりぼやかした画像にしている

![スクリーンショット 2023-06-20 23.20.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/74ca6fb0-0b1b-16b3-723e-76566cd317d9.png)


Main.storyboardにImage Viewをよしなに配置する

``` ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let ciImage = CIImage(image: imageView.image!) //Image Viewで指定したimageをCIImage化する
        
        let filter = CIFilter(name: "CIBoxBlur")! // imageにフィルターをかける
        filter.setValue(ciImage, forKey: kCIInputImageKey)
        
        let outputImage = filter.outputImage
        imageView.image = UIImage(ciImage: outputImage!) // CIImageをUIimageとして出力する
    }
}
```

# モーションセンサー

完成イメージ
iPhoneの動きを検知して画像が左右に動く

![スクリーンショット 2023-06-20 23.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/e555b639-2a3d-f4d8-4e88-62894633cb64.png)


Main.storyboardにImage Viewをよしなに配置する

``` ViewController.swift
import UIKit
import CoreMotion

class ViewController: UIViewController {
    
    let motionManager = CMMotionManager() // MotionManagerのインスタンス化
    
    @IBOutlet var fish: UIImageView! // モーションセンサーを適用したい画像

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let originalX = fish.center.x // 元の画像のx座標の中心位置を取得
        
        if motionManager.isDeviceMotionAvailable {
            motionManager.deviceMotionUpdateInterval = 0.02
            motionManager.startDeviceMotionUpdates(to: OperationQueue.current!, withHandler: {(motion, error) in
                print(motion!.attitude.roll)
                // モーション感知に合わせて新しいx座標を取得
                let newX = originalX + CGFloat(motion!.attitude.roll * 100)
// モーション感知時に座標をずらす処理
                self.fish.center = CGPoint(x: newX, y: self.fish.center.y)
            })
        }
    }
    
    func stopSensor() {
        motionManager.stopDeviceMotionUpdates()
    }


}
```

# 最後に
今回はswiftで実装できる機能の一部を簡単にまとめてみました。
swift使えば、iPhoneでできる機能を簡単に実装できてびっくりだわこりゃ

# 参考文献
https://www.udemy.com/course/ios-apps/