Как проверить, поддерживается ли Haptic Engine (UIFeedbackGenerator)
Мне интересно, как мы могли бы проверить, если новый API iOS 10 UIFeebackGenerator
доступно на текущем устройстве. Нам нужно еще кое-что проверить:
- Устройство должно работать под управлением iOS 10.0 или более поздней версии.
- Устройство должно быть iPhone 7 или новее
- Haptic Engine должен быть включен в настройках
Первые две проверки могут быть достигнуты с помощью #available(iOS 10, *)
заявление и (хакерское) обнаружение устройства, но последнее не кажется проверяемым.
Кто-нибудь знает решение для этого? Или, может быть, нам нужно подать Apple Radar для этого. Спасибо!
3 ответа
Основано на Apple UIFeedbackGenerator
документация, похоже, что iOS делает это для вас.
Обратите внимание, что вызов этих методов напрямую не влияет на тактику. Вместо этого он информирует систему о событии. Затем система определяет, следует ли воспроизводить тактильные сигналы, на основе устройства, состояния приложения, оставшегося заряда батареи и других факторов.
Например, тактильная обратная связь в настоящее время воспроизводится только:
На устройстве с поддерживаемым движком Taptic (iPhone 7 и iPhone 7 Plus).
Когда приложение работает на переднем плане.
Когда параметр System Haptics включен.
Даже если вам не нужно беспокоиться о том, может ли устройство осуществлять тактильную обратную связь, вам все равно нужно убедиться, что оно вызывается только с iOS 10 или более поздней версии, так что вы можете сделать это с помощью этого:
if #available(iOS 10,*) {
// your haptic feedback method
}
Вот краткий обзор различных опций тактильной обратной связи, доступных в iOS 10.
Там есть недокументированная "личная вещь":
UIDevice.currentDevice().valueForKey("_feedbackSupportLevel");
он возвращает 2 для устройств с тактильной обратной связью - iPhone 7/7+, так что вы можете легко использовать это для генерации обратной связи Haptic:
let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.prepare()
generator.impactOccurred()
возвращает 1 для iPhone 6S, вот запасной вариант для создания ленты:
import AudioToolbox
AudioServicesPlaySystemSound(1519) // Actuate `Peek` feedback (weak boom)
AudioServicesPlaySystemSound(1520) // Actuate `Pop` feedback (strong boom)
AudioServicesPlaySystemSound(1521) // Actuate `Nope` feedback (series of three weak booms)
и возвращает 0 для iPhone 6 или более старых устройств. Поскольку это недокументированная вещь, она может заблокировать вас на этапе проверки, хотя я смог пройти проверку и отправить приложение с такой проверкой.
Более подробная информация: http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/
На iOS 13 вы можете проверить это очень просто. Следуя этой странице документации, все, что вам нужно сделать, это:
iOS 13, Swift 5
var supportsHaptics: Bool = false
...
// Check if the device supports haptics.
let hapticCapability = CHHapticEngine.capabilitiesForHardware()
supportsHaptics = hapticCapability.supportsHaptics
Я сделал расширение для UIDevice без использования частного API
extension UIDevice {
static var isHapticsSupported : Bool {
let feedback = UIImpactFeedbackGenerator(style: .heavy)
feedback.prepare()
var string = feedback.debugDescription
string.removeLast()
let number = string.suffix(1)
if number == "1" {
return true
} else {
return false
}
}
}
и вы используете это так:
UIDevice.isHapticsSupported
возвращается true
или же false
Вы знаете, что ваше устройство поддерживает эффект Haptic вибрации или нет с приведенным ниже кодом,
UIDevice.currentDevice().valueForKey("_feedbackSupportLevel");
Эти методы, кажется, возвращают:
0 = Лента недоступна
1 = Первое поколение (протестировано на iPhone 6s) ... которое НЕ поддерживает UINotificationFeedbackGenerator и т. Д.
- 2 = Второе поколение (протестировано на iPhone 7) ... которое поддерживает его.
он возвращает 2 для устройств с тактильной обратной связью - iPhone 7/7+ или выше, так что вы можете легко использовать это для генерации обратной связи Haptic
Это будет работать для iPhone 7 и выше.
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
let myButton = UIButton(frame: CGRect(x: 0, y: 100, width: 100, height: 50))
myButton.setTitleColor(UIColor.green, for: .normal)
myButton.setTitle("Press ME", for: .normal)
myButton.addTarget(self, action: #selector(myButtonTapped), for: .touchUpInside)
self.view.addSubview(myButton)
}
@objc func myButtonTapped() {
count += 1
print("Count \(count)")
switch count {
case 1:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.error)
case 2:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)
case 3:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.warning)
case 4:
let generator = UIImpactFeedbackGenerator(style: .light)
generator.impactOccurred()
case 5:
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
case 6:
let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.impactOccurred()
default:
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
count = 0
}
}