ios 9 iphone 6S Play Haptic feedback or vibrate
Asked Answered
S

5

20

After user does force touch, I want to vibrate phone just like default behaviour.

Is it haptic? If so, how shall I do?

Somehow answered 29/9, 2015 at 10:11 Comment(0)
C
16

Example in Swift (for 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)

Just in case - here're examples for iPhone 7/7+.

As for the force touch - you need to detect if it's available first:

func is3dTouchAvailable(traitCollection: UITraitCollection) -> Bool {
    return traitCollection.forceTouchCapability == UIForceTouchCapability.available
}

and then in touch events, it will be available as touch.force

func touchMoved(touch: UITouch, toPoint pos: CGPoint) {
    let location = touch.location(in: self)
    let node = self.atPoint(location)

    //...
    if is3dTouchEnabled {
        bubble.setPressure(pressurePercent: touch.force / touch.maximumPossibleForce)
    } else {
        // ...
    }
}

Here's my blog with a more detailed example with code samples:
http://www.mikitamanko.com/blog/2017/02/01/swift-how-to-use-3d-touch-introduction/

Chet answered 5/2, 2017 at 21:18 Comment(1)
The 1519-1521 codes don't seem to apply here anymore. Did you happen to bump into issues? @Mikita MankoHispid
E
13

Starting with iOS 10, there is a new public API for handling haptic feedback: UIFeedbackGenerator.

let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)

It is suggested to call .prepare() before using the generator and sending the feedback as there is a slight delay between the two due to the feedback hardware requiring a "wakeup". This could be done in viewDidLoad() or something comparable if you are expecting the feedback to be given shortly after.

See this blog for a good explanation of the new API and the available feedbacks:
https://www.hackingwithswift.com/example-code/uikit/how-to-generate-haptic-feedback-with-uifeedbackgenerator

For iOS 9 and older, you could use AudioToolBox as outlined in the other posts.

import AudioToolbox

private let isDevice = TARGET_OS_SIMULATOR == 0

func vibrate() {
    if isDevice {
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
    }
}
Ebsen answered 6/10, 2016 at 9:26 Comment(2)
Additional haptic classes in iOS 10: UIImpactFeedbackGenerator and UISelectionFeedbackGeneratorMeasurable
@Measurable Thanks for adding the new subclasses, I don't always have a look at older posts here :)Ebsen
D
6

There are different feedback types. Try each one to figure out what is better for your needs:

// 1, 2, 3
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.error)
generator.notificationOccurred(.success)
generator.notificationOccurred(.warning)

// 4
let generator = UIImpactFeedbackGenerator(style: .light)
generator.impactOccurred()

// 5
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()

// 6
let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.impactOccurred()

// 7
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
Diffusivity answered 27/6, 2017 at 11:15 Comment(0)
S
1

I think that you are talking about the new Taptic Engine.

From apple.com: iPhone 6s gives you real-time feedback both onscreen and in the form of subtle taps from the Taptic Engine. These responses correspond to how deeply you’re pressing the display, and they let you know what actions you’re performing and what you can expect to happen.

As I know actually there is no public API for that. I've only found this tutorial for implementing the Taptic feedback via private API.

//ATTENTION: This is a private API, if you use this lines of code your app will be rejected

id tapticEngine = [[UIDevice currentDevice] performSelector:NSSelectorFromString(@"_tapticEngine") withObject:nil];
[tapticEngine performSelector:NSSelectorFromString(@"actuateFeedback:") withObject:@(0)];
Splendiferous answered 9/11, 2015 at 15:22 Comment(0)
D
0

You can use custom logic to achieve this:

  • Detect a force applied on the screen by a user, by using force and maximumPossibleForce properties of UITouch class.
  • Depending upon the force amount, you can vibrate device after particular level.

Example:

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    UITouch *touch = [touches anyObject];

    CGFloat maximumPossibleForce = touch.maximumPossibleForce;
    CGFloat force = touch.force;
    CGFloat normalizedForce = force/maximumPossibleForce;
    NSLog(@"Normalized force : %f", normalizedForce);

    if (normalizedForce > 0.75)
    {
         NSLog(@"Strong");
        // Vibrate device
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    }
    else
    {
        NSLog(@"Weak");
    }
}
  • Also, you can try to set different vibration duration for different force level with custom logic.

Example:

// Vibrate device
NSTimer * vibrationTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(vibrateDevice) userInfo:nil repeats:YES];


- (void) vibrateDevice
{
    if(duration == 2) // duration is a public variable to count vibration duration
    {
          // Stop the device vibration
          [vibrationTimer invalidate];
          return;
    }

    duration++;
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
Deathtrap answered 20/2, 2016 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.