Search code examples
objective-cxcodedelegatesuiimageviewuiaccelerometer

multiple Instances with shared UIAccelerometer not working for all instances


I have a custom UIImageView class that I want to use to control my UIImageViews.

Inside the custom init method I have the following regarding the UIAccelerometer:

    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    accelerometer.updateInterval = 0.5f;
    accelerometer.delegate = self;

My problem is that I have multiple instances of this class and the accelerometer only sends information to the last instance I create. I know the reason for this is because the delegate is being set to the last instance, so my question is:

Is there a way to set the delegate to all of these instances so all of them receive the "didAccelerate" call? If so then how would I go about it.


Solution

  • Disclaimer: the method you're trying to use is deprecated. Use CMMotionManager instead. However:

    Set one delegate (it should be a separate class), then use NSNotificationCenter to distribute the information to the other listeners. Example:

    @interface SharedAccelerometerListener: NSObject <UIAccelerometerDelegate>
    @end
    
    @implementation SharedAccelerometerListener
    
    - (id)init
    {
        if ((self = [super init]))
        {
            [UIAccelerometer sharedAccelerometer].delegate = self;
            [UIAccelerometer sharedAccelerometer].updateInterval = 0.05f;
        }
    }
    
    - (void)accelerometer:(UIAccelerometer *)acc didAccelerate:(UIAcceleration *)acceleration
    {
        NSDictionary *info = [NSDictionary dictionaryWithObject:acceleration forKey:@"acceleration"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"AccelerometerDidAccelerate" sender:nil userInfo:info];
    }
    
    @end
    

    Then in your listener class:

    id accelerationListener = [[SharedAccelerometerListener alloc] init];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didAccelerate:) name:@"AccelerometerDidAccelerate" object:nil];
    
    - (void)didAccelerate:(NSNotification *)notif
    {
        UIAcceleration *acc = [[notif userInfo] objectForKey:@"acceleration"];
        // do whatever you want with the acceleration
    }