Làm cách nào để phát hiện khi ai đó lắc iPhone?


340

Tôi muốn phản ứng khi ai đó làm rung iPhone. Tôi không đặc biệt quan tâm làm thế nào họ lắc nó, chỉ là nó được vẫy mạnh mẽ trong một giây. Có ai biết làm thế nào để phát hiện điều này?

Câu trả lời:


292

Trong 3.0, giờ đây có một cách dễ dàng hơn - nối vào các sự kiện chuyển động mới.

Thủ thuật chính là bạn cần phải có một số UIView (không phải UIViewControll) mà bạn muốn là FirstResponder để nhận các thông báo sự kiện lắc. Đây là mã mà bạn có thể sử dụng trong bất kỳ UIView nào để nhận các sự kiện lắc:

@implementation ShakingView

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if ( event.subtype == UIEventSubtypeMotionShake )
    {
        // Put in code here to handle shake
    }

    if ( [super respondsToSelector:@selector(motionEnded:withEvent:)] )
        [super motionEnded:motion withEvent:event];
}

- (BOOL)canBecomeFirstResponder
{ return YES; }

@end

Bạn có thể dễ dàng chuyển đổi bất kỳ UIView nào (ngay cả chế độ xem hệ thống) thành chế độ xem có thể nhận được sự kiện rung chỉ bằng cách phân lớp chế độ xem chỉ bằng các phương thức này (và sau đó chọn loại mới này thay vì loại cơ sở trong IB hoặc sử dụng nó khi phân bổ lượt xem).

Trong trình điều khiển chế độ xem, bạn muốn đặt chế độ xem này trở thành phản hồi đầu tiên:

- (void) viewWillAppear:(BOOL)animated
{
    [shakeView becomeFirstResponder];
    [super viewWillAppear:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
    [shakeView resignFirstResponder];
    [super viewWillDisappear:animated];
}

Đừng quên rằng nếu bạn có các chế độ xem khác trở thành phản hồi đầu tiên từ hành động của người dùng (như thanh tìm kiếm hoặc trường nhập văn bản), bạn cũng cần khôi phục trạng thái phản hồi rung đầu tiên khi chế độ xem khác từ bỏ!

Phương pháp này hoạt động ngay cả khi bạn đặt applicationSupportsShakeToEdit thành NO.


5
Điều này không hoàn toàn phù hợp với tôi: Tôi cần ghi đè lên bộ điều khiển của mình viewDidAppearthay vì viewWillAppear. Tôi cung không chăc tại sao; có lẽ khung nhìn cần phải được nhìn thấy trước khi nó có thể làm bất cứ điều gì để bắt đầu nhận các sự kiện rung lắc?
Kristopher Johnson

1
Điều này dễ dàng hơn nhưng không nhất thiết phải tốt hơn. Nếu bạn muốn phát hiện một rung lắc dài, liên tục thì phương pháp này không hữu ích vì iPhone thích kích hoạt motionEndedtrước khi rung thực sự dừng lại. Vì vậy, bằng cách sử dụng phương pháp này, bạn sẽ có được một loạt các lần lắc ngắn thay vì một lần lắc dài. Câu trả lời khác hoạt động tốt hơn nhiều trong trường hợp này.
aroth

3
@Kendall - UIViewControllers triển khai UIResponder và nằm trong chuỗi phản hồi. UIWindow trên cùng là tốt. developer.apple.com/l
Library / ios / DOCUMENTATION / EntHandling / từ

1
[super respondsToSelector:sẽ không làm những gì bạn muốn, vì nó tương đương với việc gọi [self respondsToSelector:sẽ trả lại YES. Những gì bạn cần là [[ShakingView superclass] instancesRespondToSelector:.
Vadim Yelagin

2
Thay vì sử dụng: if (event.subtype == UIEventSubtypeMotionShake), bạn có thể sử dụng: if (motion == UIEventSubtypeMotionShake)
Hashim Akhtar

179

Từ ứng dụng Diceshaker của tôi :

// Ensures the shake is strong enough on at least two axes before declaring it a shake.
// "Strong enough" means "greater than a client-supplied threshold" in G's.
static BOOL L0AccelerationIsShaking(UIAcceleration* last, UIAcceleration* current, double threshold) {
    double
        deltaX = fabs(last.x - current.x),
        deltaY = fabs(last.y - current.y),
        deltaZ = fabs(last.z - current.z);

    return
        (deltaX > threshold && deltaY > threshold) ||
        (deltaX > threshold && deltaZ > threshold) ||
        (deltaY > threshold && deltaZ > threshold);
}

@interface L0AppDelegate : NSObject <UIApplicationDelegate> {
    BOOL histeresisExcited;
    UIAcceleration* lastAcceleration;
}

@property(retain) UIAcceleration* lastAcceleration;

@end

@implementation L0AppDelegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [UIAccelerometer sharedAccelerometer].delegate = self;
}

- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

    if (self.lastAcceleration) {
        if (!histeresisExcited && L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.7)) {
            histeresisExcited = YES;

            /* SHAKE DETECTED. DO HERE WHAT YOU WANT. */

        } else if (histeresisExcited && !L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.2)) {
            histeresisExcited = NO;
        }
    }

    self.lastAcceleration = acceleration;
}

// and proper @synthesize and -dealloc boilerplate code

@end

Các histeresis ngăn sự kiện lắc kích hoạt nhiều lần cho đến khi người dùng dừng lắc.


7
Lưu ý Tôi đã thêm một câu trả lời dưới đây trình bày một phương pháp dễ dàng hơn cho 3.0.
Kendall Helmstetter Gelner

2
Điều gì xảy ra nếu họ lắc chính xác trên một trục cụ thể?
jprete

5
Câu trả lời tốt nhất, bởi vì iOS 3.0 motionBeganmotionEndedcác sự kiện không chính xác hoặc chính xác về mặt phát hiện bắt đầu và kết thúc chính xác của một lần rung. Cách tiếp cận này cho phép bạn chính xác như bạn muốn.
aroth

2
UIAccelerometerDelegate gia tốc kế: didAccelates: đã bị phản đối trong iOS5.
Yantao Xie

Câu trả lời khác này tốt hơn và nhanh hơn để thực hiện stackoverflow.com/a/2405692/396133
Abramodj

154

Cuối cùng tôi đã làm cho nó hoạt động bằng cách sử dụng các ví dụ mã từ Hướng dẫn quản lý hoàn tác / Làm lại này .
Đây chính xác là những gì bạn cần làm:

  • Đặt thuộc tính applicationSupportsShakeToEdit trong Đại biểu của ứng dụng:
  • 
        - (void)applicationDidFinishLaunching:(UIApplication *)application {
    
            application.applicationSupportsShakeToEdit = YES;
    
            [window addSubview:viewController.view];
            [window makeKeyAndVisible];
    }
    

  • Thêm / ghi đè canBecomeFirstResponder , viewDidAppear:viewWillDisappear: phương thức trong Trình điều khiển xem của bạn:
  • 
    -(BOOL)canBecomeFirstResponder {
        return YES;
    }
    
    -(void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        [self becomeFirstResponder];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [self resignFirstResponder];
        [super viewWillDisappear:animated];
    }
    

  • Thêm phương thức MotionEnded vào Trình điều khiển xem của bạn:
  • 
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (motion == UIEventSubtypeMotionShake)
        {
            // your code
        }
    }
    

    Chỉ cần thêm vào giải pháp Eran Talmor: bạn nên sử dụng bộ điều khiển điều hướng thay vì bộ điều khiển trong trường hợp bạn chọn một ứng dụng như vậy trong trình chọn dự án mới.
    Cướp

    Tôi đã thử sử dụng cái này nhưng đôi khi lắc nhẹ hoặc lắc nhẹ thì nó chỉ dừng lại
    vinothp

    Bước 1 bây giờ là dự phòng, vì giá trị mặc định applicationSupportsShakeToEditYES.
    DonVaughn

    1
    Tại sao gọi [self resignFirstResponder];trước [super viewWillDisappear:animated];? Điều này có vẻ kỳ dị.
    JaredH

    94

    Đầu tiên, câu trả lời ngày 10 tháng 7 của Kendall là tại chỗ.

    Bây giờ ... tôi muốn làm một cái gì đó tương tự (trong iPhone OS 3.0+), chỉ trong trường hợp của tôi, tôi muốn nó rộng khắp ứng dụng để tôi có thể cảnh báo các phần khác nhau của ứng dụng khi xảy ra rung lắc. Đây là những gì tôi đã làm.

    Đầu tiên, tôi phân lớp UIWindow . Điều này là dễ dàng. Tạo một tệp lớp mới với một giao diện như MotionWindow : UIWindow(cứ tự nhiên chọn lấy, chốt). Thêm một phương thức như vậy:

    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
        if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"DeviceShaken" object:self];
        }
    }
    

    Thay đổi @"DeviceShaken"tên thông báo của sự lựa chọn của bạn. Lưu các tập tin.

    Bây giờ, nếu bạn sử dụng MainWindow.xib (công cụ mẫu Xcode stock), hãy vào đó và thay đổi lớp của đối tượng Window của bạn từ UIWindow sang MotionWindow hoặc bất cứ điều gì bạn gọi nó. Lưu xib. Nếu bạn thiết lập UIWindow theo chương trình, thay vào đó hãy sử dụng lớp Window mới của bạn.

    Bây giờ ứng dụng của bạn đang sử dụng lớp UIWindow chuyên biệt . Bất cứ nơi nào bạn muốn được thông báo về một cái lắc, hãy đăng ký thông báo cho họ! Như thế này:

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(deviceShaken) name:@"DeviceShaken" object:nil];
    

    Để loại bỏ bản thân bạn như một người quan sát:

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    Tôi đặt cái của tôi vào viewWillAppear:viewWillDisappear: nơi Bộ điều khiển View có liên quan. Hãy chắc chắn rằng phản ứng của bạn đối với sự kiện lắc sẽ biết liệu nó có "đang diễn ra" hay không. Mặt khác, nếu thiết bị bị rung hai lần liên tiếp, bạn sẽ bị kẹt xe. Bằng cách này, bạn có thể bỏ qua các thông báo khác cho đến khi bạn thực sự hoàn thành việc trả lời thông báo ban đầu.

    Ngoài ra: Bạn có thể chọn để mở khóa cho khỏi motionBegan vs motionEnded . Tuỳ bạn. Trong trường hợp của tôi, hiệu ứng luôn cần diễn ra sau khi thiết bị ở trạng thái nghỉ (so với khi thiết bị bắt đầu rung), vì vậy tôi sử dụng MotionEnded . Hãy thử cả hai và xem cái nào có ý nghĩa hơn ... hoặc phát hiện / thông báo cho cả hai!

    Thêm một quan sát (tò mò?) Ở đây: Lưu ý rằng không có dấu hiệu quản lý phản hồi đầu tiên trong mã này. Cho đến nay tôi chỉ thử điều này với Bộ điều khiển xem bảng và mọi thứ dường như hoạt động khá tốt với nhau! Tôi không thể đảm bảo cho các kịch bản khác mặc dù.

    Kendall, et. al - có ai có thể nói lý do tại sao điều này có thể như vậy đối với các lớp con UIWindow không? Có phải vì cửa sổ nằm ở đầu chuỗi thức ăn?


    1
    Điều đó thật kỳ lạ. Nó hoạt động như vốn có. Hy vọng rằng đó không phải là một trường hợp "làm việc bất chấp chính nó"! Xin vui lòng cho tôi biết những gì bạn tìm ra trong thử nghiệm của riêng bạn.
    Joe D'Andrea

    Tôi thích điều này để phân lớp một UIView thông thường, đặc biệt vì bạn chỉ cần điều này tồn tại ở một nơi, vì vậy việc đặt trong một lớp con cửa sổ có vẻ phù hợp tự nhiên.
    Ếch xù xì

    Cảm ơn bạn jdandrea, tôi sử dụng phương pháp của bạn nhưng run rẩy nhiều lần !!! tôi chỉ muốn người dùng có thể lắc một lần (trên quan điểm rằng rung lắc ở đó) ...! Làm thế nào tôi có thể xử lý nó? tôi thực hiện sth như thế này. Tôi triển khai mã của mình như thế này: i-phone.ir/forums/uploadedpictures/, ---- nhưng vấn đề là ứng dụng chỉ rung 1 lần trong vòng đời của ứng dụng! không chỉ xem
    Momi

    1
    Momeks: Nếu bạn cần thông báo xảy ra khi thiết bị ở trạng thái nghỉ (rung sau), hãy sử dụng MotionEnded thay vì motionBegan. Điều đó nên làm điều đó!
    Joe D'Andrea

    1
    @Joe D'Andrea - Nó hoạt động như vốn có vì UIWindow nằm trong chuỗi phản hồi. Nếu thứ gì đó cao hơn chuỗi bị chặn và tiêu thụ những sự kiện này, nó sẽ không nhận được chúng. developer.apple.com/l
    Library / ios / DOCUMENTATION / EntHandling / từ

    34

    Tôi đã xem qua bài đăng này để tìm kiếm một thực hiện "lắc". Câu trả lời của millenomi hoạt động tốt với tôi, mặc dù tôi đang tìm kiếm thứ gì đó đòi hỏi một chút "hành động lắc" để kích hoạt. Tôi đã thay thế giá trị Boolean bằng int ShakeCount. Tôi cũng đã thực hiện lại phương thức L0AccelutionsIsShaking () trong Objective-C. Bạn có thể điều chỉnh lượng đạn cần thiết bằng cách điều chỉnh số lượng đạn được thêm vào ShakeCount. Tôi không chắc chắn tôi đã tìm thấy các giá trị tối ưu chưa, nhưng có vẻ như nó vẫn hoạt động tốt cho đến nay. Hy vọng điều này sẽ giúp ai đó:

    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
        if (self.lastAcceleration) {
            if ([self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.7] && shakeCount >= 9) {
                //Shaking here, DO stuff.
                shakeCount = 0;
            } else if ([self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.7]) {
                shakeCount = shakeCount + 5;
            }else if (![self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.2]) {
                if (shakeCount > 0) {
                    shakeCount--;
                }
            }
        }
        self.lastAcceleration = acceleration;
    }
    
    - (BOOL) AccelerationIsShakingLast:(UIAcceleration *)last current:(UIAcceleration *)current threshold:(double)threshold {
        double
        deltaX = fabs(last.x - current.x),
        deltaY = fabs(last.y - current.y),
        deltaZ = fabs(last.z - current.z);
    
        return
        (deltaX > threshold && deltaY > threshold) ||
        (deltaX > threshold && deltaZ > threshold) ||
        (deltaY > threshold && deltaZ > threshold);
    }
    

    Tái bút: Tôi đã đặt khoảng thời gian cập nhật là 1/15 giây.

    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 15)];

    Làm thế nào tôi có thể phát hiện chuyển động của thiết bị giống như toàn cảnh?
    user2526811

    Làm cách nào để xác định rung nếu iphone chỉ được di chuyển theo hướng X? Tôi không muốn phát hiện rung nếu theo hướng Y hoặc Z.
    Thần chú

    12

    Bạn cần kiểm tra gia tốc kế thông qua gia tốc kế: didAccelates: phương thức là một phần của giao thức UIAccelerometerDelegate và kiểm tra xem các giá trị có vượt quá ngưỡng chuyển động cần thiết cho một lần lắc hay không.

    Có một mã mẫu khá trong gia tốc kế: didAccelREE: phương thức ngay ở cuối AppControll.m trong ví dụ GLPaint có sẵn trên trang web dành cho nhà phát triển iPhone.


    12

    Trong iOS 8.3 (có lẽ sớm hơn) với Swift, đơn giản như ghi đè motionBeganhoặc motionEndedcác phương thức trong trình điều khiển chế độ xem của bạn:

    class ViewController: UIViewController {
        override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent) {
            println("started shaking!")
        }
    
        override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) {
            println("ended shaking!")
        }
    }

    Bạn đã thử à? Tôi giả định rằng để làm cho điều này hoạt động khi ứng dụng ở chế độ nền sẽ cần thêm một chút công việc.
    nhgrif

    Không .. sẽ sớm .. nhưng nếu bạn nhận thấy iPhone 6s thì nó có tính năng "chọn lấy màn hình", trong đó màn hình sẽ sáng lên một lúc, khi bạn cầm thiết bị lên. Tôi cần phải nắm bắt hành vi này
    nr5

    9

    Đây là mã đại biểu cơ bản bạn cần:

    #define kAccelerationThreshold      2.2
    
    #pragma mark -
    #pragma mark UIAccelerometerDelegate Methods
        - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 
        {   
            if (fabsf(acceleration.x) > kAccelerationThreshold || fabsf(acceleration.y) > kAccelerationThreshold || fabsf(acceleration.z) > kAccelerationThreshold) 
                [self myShakeMethodGoesHere];   
        }

    Đồng thời đặt mã thích hợp trong Giao diện. I E:

    @interface MyViewCont Bộ điều khiển: UIViewCont Bộ điều khiển <UIPickerViewDelegate, UIPickerViewDataSource, UIAccelerometerDelegate>


    Làm thế nào tôi có thể phát hiện chuyển động của thiết bị giống như toàn cảnh?
    dùng2526811

    Làm cách nào để xác định rung nếu iphone chỉ được di chuyển theo hướng X? Tôi không muốn phát hiện rung nếu theo hướng Y hoặc Z.
    Thần chú


    7

    Thêm các phương thức sau trong tệp ViewControll.m, nó hoạt động đúng

        -(BOOL) canBecomeFirstResponder
        {
             /* Here, We want our view (not viewcontroller) as first responder 
             to receive shake event message  */
    
             return YES;
        }
    
        -(void) motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
        {
                if(event.subtype==UIEventSubtypeMotionShake)
                {
                        // Code at shake event
    
                        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Motion" message:@"Phone Vibrate"delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                        [alert show];
                        [alert release];
    
                        [self.view setBackgroundColor:[UIColor redColor]];
                 }
        }
        - (void)viewDidAppear:(BOOL)animated
        {
                 [super viewDidAppear:animated];
                 [self becomeFirstResponder];  // View as first responder 
         }

    5

    Xin lỗi để đăng bài này dưới dạng câu trả lời thay vì nhận xét nhưng như bạn có thể thấy tôi mới biết về Stack Overflow và vì vậy tôi chưa đủ uy tín để đăng bình luận!

    Dù sao, tôi thứ hai @cire về việc đảm bảo đặt trạng thái phản hồi đầu tiên một khi chế độ xem là một phần của hệ thống phân cấp chế độ xem. Vì vậy, thiết lập trạng thái phản hồi đầu tiên trong viewDidLoadphương thức bộ điều khiển xem của bạn sẽ không hoạt động. Và nếu bạn không chắc chắn liệu nó có hoạt động hay không [view becomeFirstResponder]sẽ trả về cho bạn một boolean mà bạn có thể kiểm tra.

    Một điểm khác: bạn có thể sử dụng bộ điều khiển chế độ xem để ghi lại sự kiện rung nếu bạn không muốn tạo một lớp con UIView một cách không cần thiết. Tôi biết nó không quá rắc rối nhưng vẫn có tùy chọn ở đó. Chỉ cần di chuyển các đoạn mã mà Kendall đưa vào lớp con UIView vào bộ điều khiển của bạn và gửi becomeFirstResponderresignFirstRespondertin nhắn đến selfthay vì lớp con UIView.


    Điều này không cung cấp một câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ một tác giả, hãy để lại nhận xét bên dưới bài đăng của họ.
    Alex Salauyou

    @SashaSalauyou Tôi đã tuyên bố rõ ràng trong câu đầu tiên ở đây Tôi không đủ uy tín để đăng bình luận vào thời điểm đó
    Newtz

    lấy làm tiếc. Có thể ở đây để câu trả lời 5-yo đánh vào hàng đánh giá))
    Alex Salauyou

    5

    Trước hết, tôi biết đây là một bài viết cũ, nhưng nó vẫn có liên quan và tôi thấy rằng hai câu trả lời được bình chọn cao nhất đã không phát hiện ra sự rung chuyển càng sớm càng tốt . Đây là cách thực hiện:

    1. Liên kết CoreMotion với dự án của bạn trong các giai đoạn xây dựng của mục tiêu: CoreMotion
    2. Trong ViewContoder của bạn:

      - (BOOL)canBecomeFirstResponder {
          return YES;
      }
      
      - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
      {
          if (motion == UIEventSubtypeMotionShake) {
              // Shake detected.
          }
      }

    4

    Giải pháp dễ nhất là lấy ra một cửa sổ gốc mới cho ứng dụng của bạn:

    @implementation OMGWindow : UIWindow
    
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
        if (event.type == UIEventTypeMotion && motion == UIEventSubtypeMotionShake) {
            // via notification or something   
        }
    }
    @end

    Sau đó, trong đại biểu ứng dụng của bạn:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        self.window = [[OMGWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        //…
    }

    Nếu bạn đang sử dụng Storyboard, điều này có thể phức tạp hơn, tôi không biết chính xác mã bạn sẽ cần trong ứng dụng ủy nhiệm chính xác.


    Và vâng, bạn có thể lấy được lớp cơ sở của mình trong @implementationXcode 5.
    mxcl

    Điều này hoạt động, tôi sử dụng nó trong một số ứng dụng. Vì vậy, không chắc chắn tại sao nó đã được bỏ phiếu xuống.
    mxcl

    làm việc như người ở. Trong trường hợp bạn đang tự hỏi, bạn có thể ghi đè lớp cửa sổ như thế này: stackoverflow.com/a/10580083/709975
    Edu

    Điều này sẽ hoạt động khi ứng dụng ở chế độ nền? Nếu không có ý tưởng nào khác làm thế nào để phát hiện khi ở chế độ nền?
    nr5

    Điều này có thể sẽ hoạt động nếu bạn có một bộ chế độ nền.
    mxcl

    1

    Chỉ cần sử dụng ba phương pháp này để làm điều đó

    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
    - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{

    để biết chi tiết bạn có thể kiểm tra một mã ví dụ hoàn chỉnh ở đó


    1

    Một phiên bản swiftease dựa trên câu trả lời đầu tiên!

    override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
        if ( event?.subtype == .motionShake )
        {
            print("stop shaking me!")
        }
    }

    -1

    Để kích hoạt toàn ứng dụng này, tôi đã tạo một danh mục trên UIWindow:

    @implementation UIWindow (Utils)
    
    - (BOOL)canBecomeFirstResponder
    {
        return YES;
    }
    
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (motion == UIEventSubtypeMotionShake) {
            // Do whatever you want here...
        }
    }
    
    @end
    Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
    Licensed under cc by-sa 3.0 with attribution required.