11
1

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 5 years have passed since last update.

Swift その2Advent Calendar 2016

Day 21

UIFeedbackGeneratorをiOS10未満対応アプリで楽に書けるUtility

Posted at

UIFeedbackGenerator

iOS10にてUIFeedbackGeneratorというAPIが追加されています。

"iOS10 + iPhone7のTapticEngine" をアプリ内から操作できるAPIです。
iPhone7だと UISwitchやUIScrollViewなどの操作時に「パコッ!」というフィードバックがありますよね。あれっす。

iOS10の時だけ実行されるUIFeedbackGeneratorのラッパークラスを作りました

これを自分のプロジェクトにも導入しようと思いましたがiOS10未満もサポートしているため都度 #availableが必要になってしまいます。
もう少し気軽にフィードバックを追加していきたいなと思ったので、
ややdynamicな感じですがiOS10の時だけ実行されるUIFeedbackGeneratorのラッパーAPIを用意してみました。

使い方はこんな感じ

// Notification
NotificationFeedbacker().feedback(style: .success)

// Impact
ImpactFeedbacker(style: .heavy).feedback()

// Selection
SelectionFeedbacker()

ソースコード

以下ソースコードです。

import UIKit

public final class ImpactFeedbacker {

  public enum Style {
    case light
    case medium
    case heavy
  }

  @available(iOS 10.0, *)
  private var feedbackGenerator: UIImpactFeedbackGenerator? {
    get {
      return feedbackGeneratorSource as? UIImpactFeedbackGenerator
    }
    set {
      feedbackGeneratorSource = newValue
    }
  }

  private var feedbackGeneratorSource: Any?

  public init(style: Style) {
    if #available(iOS 10.0, *) {
      switch style {
      case .light:
        feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
      case .medium:
        feedbackGenerator = UIImpactFeedbackGenerator(style: .medium)
      case .heavy:
        feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy)
      }
      feedbackGenerator?.prepare()
    } else {
      feedbackGeneratorSource = nil
    }
  }

  public func feedback() {
    if #available(iOS 10.0, *) {
      feedbackGenerator?.impactOccurred()
      feedbackGenerator?.prepare()
    } else {
    }
  }
}

public final class SelectionFeedbacker {

  @available(iOS 10.0, *)
  private var feedbackGenerator: UISelectionFeedbackGenerator? {
    get {
      return feedbackGeneratorSource as? UISelectionFeedbackGenerator
    }
    set {
      feedbackGeneratorSource = newValue
    }
  }

  private var feedbackGeneratorSource: Any?

  public init() {
    if #available(iOS 10.0, *) {
      feedbackGenerator = UISelectionFeedbackGenerator()
      feedbackGenerator?.prepare()
    } else {
      feedbackGeneratorSource = nil
    }
  }

  public func feedback() {
    if #available(iOS 10.0, *) {
      feedbackGenerator?.selectionChanged()
      feedbackGenerator?.prepare()
    } else {
    }
  }
}

public final class NotificationFeedbacker {

  public enum Style {
    case success
    case warning
    case error
  }

  @available(iOS 10.0, *)
  private var feedbackGenerator: UINotificationFeedbackGenerator? {
    get {
      return feedbackGeneratorSource as? UINotificationFeedbackGenerator
    }
    set {
      feedbackGeneratorSource = newValue
    }
  }

  private var feedbackGeneratorSource: Any?

  public init() {
    if #available(iOS 10.0, *) {
      feedbackGenerator = UINotificationFeedbackGenerator()
      feedbackGenerator?.prepare()
    } else {
      feedbackGeneratorSource = nil
    }
  }

  public func feedback(style: Style) {
    if #available(iOS 10.0, *) {
      switch style {
      case .success:
        feedbackGenerator?.notificationOccurred(.success)
      case .warning:
        feedbackGenerator?.notificationOccurred(.warning)
      case .error:
        feedbackGenerator?.notificationOccurred(.error)
      }
      feedbackGenerator?.prepare()
    } else {
    }
  }
}

補足

「パコッ!」 が気持ちよすぎて全てのボタンに追加したくなってしまいますが、そういうわけにはいかないんですね。

Appleのガイドラインには適切な使い方が記述されていました。

まとめ

パコッ!

11
1
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
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?