ทำให้ iPhone สั่นสะเทือน


228

iPhone จะสั่นได้อย่างไร?

ตัวอย่างเช่นเมื่อผู้เล่นเสียชีวิตหรือเกมจบลง iPhone จะสั่นสะเทือน


9
ท่าทางการสั่นนั้นแตกต่างจากการสั่นสะเทือนอย่างสิ้นเชิง หนึ่งคือมนุษย์เริ่มอุปกรณ์หนึ่งเริ่ม
Eiko

คำตอบ:


404

จาก " บทช่วยสอน iPhone: วิธีที่ดีกว่าในการตรวจสอบความสามารถของอุปกรณ์ iOS ":

มีฟังก์ชั่นที่คล้ายกันสองฟังก์ชั่นที่รับพารามิเตอร์kSystemSoundID_Vibrate:

1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

ฟังก์ชั่นทั้งสองสั่นสะเทือน iPhone แต่เมื่อคุณใช้ฟังก์ชั่นแรกบนอุปกรณ์ที่ไม่รองรับการสั่นสะเทือนมันจะส่งเสียงบี๊บ ในทางกลับกันฟังก์ชั่นที่สองไม่ได้ทำอะไรกับอุปกรณ์ที่ไม่รองรับ ดังนั้นหากคุณกำลังสั่นสะเทือนอุปกรณ์อย่างต่อเนื่องตามสามัญสำนึกพูดว่าสามัญสำนึกใช้ฟังก์ชัน 2

ขั้นแรกเพิ่มเฟรมเวิร์ก AudioToolbox AudioToolbox.frameworkให้กับเป้าหมายของคุณใน Build Phases

จากนั้นนำเข้าไฟล์ส่วนหัวนี้:

#import <AudioToolbox/AudioServices.h>

3
#import <Cocoa / Cocoa.h> ไม่จำเป็น
Raptor

10
มีวิธีใดที่จะลดเวลาการสั่นสะเทือนให้น้อยกว่า 1 วินาทีหรือไม่
George Asda

11
ฉันต้องการเพิ่มว่าหากการสั่นสะเทือนถูกปิดในการตั้งค่าของ iOS ผู้ใช้จะไม่ได้รับการสั่นสะเทือนแม้ว่าคุณจะใช้คำสั่งเหล่านี้
เดนิส Kutlubaev

7
ใน Swift: AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))(อย่างน้อยก็ในรุ่นเบต้า 2)
Sam Soffes

1
AudioServicesPlayAlertSound (kSystemSoundID_Vibrate); Vibarate บน iPhone อย่างระมัดระวัง แต่ไม่ส่งเสียงบี๊บบน iPad
Mangesh

45

Swift 2.0+

ตอนนี้ AudioToolbox นำเสนอประเภทkSystemSoundID_Vibrateเป็นSystemSoundIDดังนั้นรหัสคือ:

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

แทนที่จะต้องผ่านขั้นตอนการร่ายพิเศษ

(อุปกรณ์ประกอบฉากเพื่อ @Dov)

คำตอบเดิม (Swift 1.x)

และนี่คือวิธีที่คุณทำกับสวิฟท์ (ในกรณีที่คุณพบปัญหาเช่นเดียวกับฉัน)

เชื่อมโยงกับAudioToolbox.framework(ไปที่โครงการของคุณเลือกเป้าหมายของคุณสร้างเฟสเชื่อมโยงไบนารีกับไลบรารีเพิ่มไลบรารีที่นั่น)

เมื่อเสร็จแล้ว:

import AudioToolbox.AudioServices

// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))

สิ่งที่วิเศษเป็นที่SystemSoundIDเป็นพื้นtypealias(SWIFT แฟนซีtypedef) สำหรับUInt32และเป็นปกติkSystemSoundID_Vibrate Intคอมไพเลอร์ให้ข้อผิดพลาดในการพยายามส่งจากIntถึงUInt32แต่ข้อผิดพลาดจะอ่านว่า "ไม่สามารถแปลงเป็น SystemSoundID" ซึ่งทำให้เกิดความสับสน ทำไมแอปเปิ้ลไม่เพียงแค่ทำให้ Swift Enum อยู่เหนือฉัน

@ aponomarenko รายละเอียดคำตอบของฉันคือ Swifters ที่นั่น


ดูเหมือนว่าจะได้รับการแก้ไขใน Swift 2 / iOS 9 / Xcode 7 ฉันใช้AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)และรวบรวมได้ดี
Dov

35

วิธีง่ายๆในการดำเนินการดังกล่าวคือบริการเสียง:

#import <AudioToolbox/AudioToolbox.h> 
...    
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

3
#import <AudioToolbox / AudioToolbox.h> และคุณจะต้องเพิ่ม AudioToolbox.framework ไปยัง Build Phases ของโครงการของคุณ
Michael Mangold

31

ฉันมีปัญหาอย่างมากกับสิ่งนี้สำหรับอุปกรณ์ที่มีการสั่นสะเทือนถูกปิดในบางลักษณะ แต่เราต้องการให้มันทำงานโดยไม่คำนึงถึงเพราะมันมีความสำคัญอย่างยิ่งต่อการทำงานของแอปพลิเคชันของเราและเนื่องจากมันเป็นเพียงจำนวนเต็ม การตรวจสอบ ดังนั้นฉันจึงลองเสียงที่อยู่นอกเสียงที่บันทึกไว้ที่นี่: TUNER88 / iOSSystemSoundsLibrary

ฉันได้สะดุดแล้วเมื่อ 1352 (Settings->vibrate on ring, vibrate on silent)ซึ่งมีการทำงานโดยไม่คำนึงถึงสวิทช์เงียบหรือการตั้งค่าบนอุปกรณ์

- (void)vibratePhone;
{
     if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
     {
         AudioServicesPlaySystemSound (1352); //works ALWAYS as of this post
     }
     else
     {
          // Not an iPhone, so doesn't have vibrate
          // play the less annoying tick noise or one of your own
          AudioServicesPlayAlertSound (1105);
     }
}

7
จะดีกว่าเสมอหากใช้นามแฝงที่มีชื่อแทนค่าคงที่เวทย์มนตร์เช่น kSystemSoundID_Vibrate แทน 1352 ฉันขอแนะนำให้คุณอัปเดตคำตอบของคุณ
nalexn

3
ฉันเห็นด้วยกับการใช้เวทย์มนตร์ 1352 นี้ไม่เหมาะ แต่ฉันไม่สามารถหาวิธีอื่น ๆ ในการบังคับให้มีการสั่นสะเทือนแม้ว่าจะปิดสวิตช์การสั่นสะเทือนบนอุปกรณ์ นี่น่าจะเป็นหนทางเดียวเท่านั้น
marcshilling

4
ฉันเขียน a สำหรับ loop ที่มีจำนวนเต็มเริ่มต้นจากค่าคงที่ที่เผยแพร่และคิดออกว่าอันไหนที่ทำให้เกิดการสั่นสะเทือน
Joel Teply

2
ฉันสามารถยืนยันได้ว่า iPhone สั่นแม้ว่าจะเปิดใช้งานโหมดเงียบใน iPhone คำตอบที่ดี!
vomako

2
AudioServicesPlaySystemSound (1352) ยังคงใช้งานได้กับ iPhone โดยไม่คำนึงถึงตำแหน่งสวิตช์เงียบ ณ เดือนมกราคม 2016
JustAnotherCoder

26

หมายเหตุสำคัญ: การเตือนการเสื่อมราคาในอนาคต

ในฐานะของiOS 9.0ที่APIคำอธิบายฟังก์ชั่นสำหรับ:

AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)

รวมถึงหมายเหตุต่อไปนี้:

This function will be deprecated in a future release.
Use AudioServicesPlayAlertSoundWithCompletion or  
AudioServicesPlaySystemSoundWithCompletion instead.

วิธีที่ถูกต้องในการไปใช้สองสิ่งต่อไปนี้:

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)

หรือ

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
 //your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}

อย่าลืม import AVFoundation


คุณไม่มีคำสั่งการนำเข้า
Juan Boero

นำเข้า AudioToolbox.AudioServices
Hugo Alonso

ฉันทำด้วยตัวเองเพียงกับ AVFoundation
Juan Boero

ยังไงก็ตามที่จะตั้งระยะเวลาของการสั่นสะเทือน?
Micro

คุณจะต้องเชื่อมต่อการโทรหลายสายใช้เวลาล่วงเลยในระหว่างการโทรใหม่ทุกครั้ง
Hugo Alonso

7

สำหรับ iPhone 7/7 Plus หรือใหม่กว่าให้ใช้ API ข้อเสนอแนะ Haptic ทั้งสามนี้

API ที่พร้อมใช้งาน

สำหรับการแจ้งเตือน:

let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)

รูปแบบที่มีอยู่.error, และ.success .warningแต่ละห้องมีความรู้สึกโดดเด่นเป็นของตัวเอง
จากเอกสาร :

UIFeedbackGeneratorคลาสย่อยที่เป็นรูปธรรมที่สร้าง haptics เพื่อสื่อสารความสำเร็จความล้มเหลวและคำเตือน

สำหรับการสั่นสะเทือนอย่างง่าย:

let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()

รูปแบบที่มีอยู่.heavy, และ.medium .lightสิ่งเหล่านี้คือการสั่นสะเทือนอย่างง่ายที่มี "ความแข็ง" ที่แตกต่างกันไป
จากเอกสาร :

UIFeedbackGeneratorคลาสย่อยคอนกรีตที่สร้าง haptics เพื่อจำลองผลกระทบทางกายภาพ

สำหรับเมื่อผู้ใช้เลือกรายการ

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

นี่เป็นสิ่งที่สังเกตได้น้อยที่สุดเกี่ยวกับการรับสัมผัสทั้งหมดดังนั้นจึงเหมาะที่สุดสำหรับเมื่อไม่ควรสัมผัสประสบการณ์การใช้แอพ
จากเอกสาร :

UIFeedbackGeneratorคลาสย่อยคอนกรีตที่สร้าง haptics เพื่อระบุการเปลี่ยนแปลงในการเลือก

หมายเหตุ

มีสองสิ่งที่ควรจดจำเมื่อใช้ API เหล่านี้

หมายเหตุ

คุณไม่ได้สร้างสัมผัสจริง คุณร้องขอให้ระบบสร้างแฮบติค ระบบจะตัดสินใจตามด้านล่าง:

  • ถ้าเป็นไปได้บนอุปกรณ์ (ไม่ว่าจะเป็น Taptic Engine ในกรณีนี้)
  • ระบุว่าแอพอาจบันทึกเสียง (ไม่ได้สร้างระบบสัมผัสระหว่างการบันทึกเพื่อป้องกันการรบกวนที่ไม่พึงประสงค์)
  • เปิดใช้งานระบบสัมผัสในการตั้งค่าระบบหรือไม่

ดังนั้นระบบจะเพิกเฉยต่อคำขอของคุณสำหรับการรับสัมผัสแบบเงียบ ๆ หากไม่สามารถทำได้ หากนี่เป็นเพราะอุปกรณ์ที่ไม่รองรับคุณสามารถลอง:

func haptic() {
    // Get whether the device can generate haptics or not
    // If feedbackSupportLevel is nil, will assign 0
    let feedbackSupportLevel = UIDevice.current.value(forKey: "_feedbackSupportLevel") as? Int ?? 0

    switch feedbackSupportLevel { 
    case 2:
        // 2 means the device has a Taptic Engine
        // Put Taptic Engine code here, using the APIs explained above

    case 1: 
    // 1 means no Taptic Engine, but will support AudioToolbox
    // AudioToolbox code from the myriad of other answers!

    default: // 0
        // No haptic support
        // Do something else, like a beeping noise or LED flash instead of haptics
    }

แทนที่ความคิดเห็นในswitch-caseคำสั่งและรหัสการสร้างแบบสัมผัสนี้จะพกพาไปยังอุปกรณ์ iOS อื่น ๆ มันจะสร้างระดับสูงสุดของความเป็นไปได้สัมผัส

หมายเหตุข

  • เนื่องจากความจริงที่ว่าการสร้าง haptics เป็นงานระดับฮาร์ดแวร์อาจมีเวลาแฝงอยู่ระหว่างเมื่อคุณเรียกรหัส haptic-generation และเมื่อมันเกิดขึ้นจริง ด้วยเหตุนี้ Taptic Engine API ทั้งหมดจึงมีprepare()วิธีที่จะทำให้มันอยู่ในสภาพพร้อม ตัวอย่างการใช้เกมของคุณ: คุณอาจรู้ว่าเกมกำลังจะจบลงโดยผู้ใช้ที่มี HP ต่ำมากหรือสัตว์ประหลาดที่อันตรายอยู่ใกล้พวกเขา
  • หากคุณไม่สร้างแฮบติคภายในสองสามวินาที Taptic Engine จะกลับสู่สถานะว่าง (เพื่อประหยัดแบตเตอรี่)


ในกรณีนี้การเตรียม Taptic Engine จะสร้างประสบการณ์ที่มีคุณภาพและตอบสนองได้ดีขึ้น

ตัวอย่างเช่นสมมติว่าแอปของคุณใช้ตัวจดจำท่าทางเลื่อนเพื่อเปลี่ยนส่วนของโลกที่มองเห็นได้ คุณต้องการแฮบติคที่จะสร้างเมื่อผู้ใช้ 'ดู' รอบ 360 องศา นี่คือวิธีที่คุณสามารถใช้prepare():

@IBAction func userChangedViewablePortionOfWorld(_ gesture: UIPanGestureRecogniser!) {

    haptic = UIImpactFeedbackGenerator(style: .heavy)

    switch gesture.state {
        case .began:
            // The user started dragging the screen.
            haptic.prepare()

        case .changed:
            // The user trying to 'look' in another direction
            // Code to change viewable portion of the virtual world

            if virtualWorldViewpointDegreeMiddle = 360.0 { 
                haptic.impactOccured()
            }
        
        default:
            break

} 

อย่าลืมimport UIKit!
Benj

คุณไม่ต้องการที่จะสร้างตัวอย่างใหม่ของhapticภายในวิธีนี้ คุณยังไม่ได้เรียกร้องในกรณีเดียวกันกับที่คุณเรียกimpactOccured prepare
rmaddy


5

ในการเดินทางของฉันฉันพบว่าหากคุณลองทำอย่างใดอย่างหนึ่งต่อไปนี้ในขณะที่คุณกำลังบันทึกเสียงอุปกรณ์จะไม่สั่นแม้ว่าจะเปิดใช้งานอยู่ก็ตาม

1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

วิธีการของฉันถูกเรียกในเวลาที่กำหนดในการวัดความเคลื่อนไหวของอุปกรณ์ ฉันต้องหยุดการบันทึกแล้วเริ่มต้นใหม่หลังจากการสั่นสะเทือนเกิดขึ้น

ดูเหมือนว่านี้

-(void)vibrate {
    [recorder stop];
    AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
    [recorder start];
}

recorder เป็นอินสแตนซ์ของ AVRecorder

หวังว่านี่จะช่วยผู้อื่นที่เคยมีปัญหาแบบเดียวกันมาก่อน


4

ใน iOS 10 และบน iPhone รุ่นใหม่กว่าคุณสามารถใช้ haptic API ได้ ผลตอบรับแบบสัมผัสนี้อ่อนกว่า AudioToolbox API

สำหรับสถานการณ์ GAME OVER ของคุณผลตอบรับ UI ที่หนักควรเหมาะสม

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

คุณสามารถใช้อื่น ๆ รูปแบบสัมผัสความคิดเห็น



0

ในกรณีของฉันฉันใช้ AVCaptureSession AudioToolbox อยู่ในช่วงการสร้างของโครงการและนำเข้าแล้วแต่ยังใช้งานไม่ได้ เพื่อให้มันทำงานได้ฉันหยุดเซสชันก่อนการสั่นสะเทือนและดำเนินการต่อหลังจากนั้น

#import <AudioToolbox/AudioToolbox.h>
...
@property (nonatomic) AVCaptureSession *session;
...
- (void)vibratePhone;
{
  [self.session stopRunning];
     NSLog(@"vibratePhone %@",@"here");
    if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
    {
        AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); 
    }
    else
    {
        AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
    }
  [self.session startRunning];
}

-5

คุณสามารถใช้ได้

1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);

สำหรับ iPhone และ iPod รุ่นใหม่กว่า

2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

สำหรับ iPads


3
iPod touch และ iPads ไม่สามารถสั่นสะเทือนได้
DDPWNAGE

1
บนอุปกรณ์ที่ไม่มีความสามารถในการสั่นสะเทือน (เช่น iPod Touch) สิ่งนี้จะไม่ทำอะไรเลย
Lal Krishna
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.