danielamitay/DAAnisotropicImage

thumbImage not aligned when UISlider is put in UIToolbar

Closed this issue · 2 comments

The slider with DAAnisotrapicImage is working perfectly but when I put the slider in a UIToolbar the thumbImage appears a bit too low. You can see an example here: https://www.dropbox.com/s/f2d37xi2i54syae/Screen%20Shot%202012-09-02%20at%2019.09.03.png

I'm not really sure that this is an issue with DAAnisotropicImage but the previous default slider that I used did not have this problem.

The code that I use to customize the UISlider view inside a MPVolumeView:

-(void) customizeSlider{
MPVolumeView *volumeView = self.volumeView;
NSArray *tempArray = volumeView.subviews;

for (id current in tempArray){
    if ([current isKindOfClass:[UISlider class]]){
        self.tempSlider = (UISlider *) current;
        self.tempSlider.frame = CGRectMake(20.0f, 180.0f, 280.0f, 40.0f);

        UIImage *stretchableFillImage = [[UIImage imageNamed:@"slider-fill"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 6.0f, 0.0f, 6.0f)];
        UIImage *stretchableTrackImage = [[UIImage imageNamed:@"slider-track"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 6.0f, 0.0f, 6.0f)];
        [self.tempSlider setMinimumTrackImage:stretchableFillImage forState:UIControlStateNormal];
        [self.tempSlider setMaximumTrackImage:stretchableTrackImage forState:UIControlStateNormal];

        UIImage *initialImage = [DAAnisotropicImage imageFromAccelerometerData:nil];
        [self.tempSlider setThumbImage:initialImage forState:UIControlStateNormal];
        [self.tempSlider setThumbImage:initialImage forState:UIControlStateHighlighted];

        [self.tempSlider setThumbImage:[UIImage imageNamed:@"thumbImage.png"] forState:UIControlStateNormal];

    }
}

//start updating image
[DAAnisotropicImage startAnisotropicUpdatesWithHandler:^(UIImage *image) {
    [self.tempSlider setThumbImage:image forState:UIControlStateNormal];
    [self.tempSlider  setThumbImage:image forState:UIControlStateHighlighted];
}];

[self.volumeView removeFromSuperview];
[self.view addSubview:volumeView];

}

Interesting. Indeed, this is not an issue with DAAnisotropicImage (simply changing the thumb tint color causes the same mis-alignment).

Here's the issue:

The UISlider in the MPVolumeView is actually an MPVolumeSlider. MPVolumeSlider overrides thumbRectForBounds:trackRect:value:, which pushes the thumbRect a few pixels down.

Here's the solution:

You need to method swizzle MPVolumeSlider's thumbRectForBounds:trackRect:value: with your own thumbRectForBounds:trackRect:value: (that simply returns the default UISlider implementation.


Relevant links:

Same problem as you: http://stackoverflow.com/questions/11230552/custom-mpvolumeview-thumb-image-not-vertically-centered-since-ios-5-1

Full customization example + your solution: http://tibr.me/2012/07/14/customizing-mpvolumeview-appearance/


This isn't the nicest solution, but a solution nonetheless to a problem which MPVolumeSlider causes. I'll leave this issue open for now, so please come back with your results or decision.

Hi, thank you for your very helpfull response. I used the solution on http://tibr.me/2012/07/14/customizing-mpvolumeview-appearance/ and it works perfectly: the thumbImage is now correctly positioned on the slider.

Corrected code:
-(void) customizeSlider{
MPVolumeView *volumeView = self.volumeView;
NSArray *tempArray = volumeView.subviews;

for (id current in tempArray){
    if ([current isKindOfClass:[UISlider class]]){
        self.tempSlider = (UISlider *) current;

        UIImage *stretchableFillImage = [[UIImage imageNamed:@"slider-fill"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 6.0f, 0.0f, 6.0f)];
        UIImage *stretchableTrackImage = [[UIImage imageNamed:@"slider-track"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 6.0f, 0.0f, 6.0f)];
        [self.tempSlider setMinimumTrackImage:stretchableFillImage forState:UIControlStateNormal];
        [self.tempSlider setMaximumTrackImage:stretchableTrackImage forState:UIControlStateNormal];

        UIImage *initialImage = [DAAnisotropicImage imageFromAccelerometerData:nil];
        [self.tempSlider setThumbImage:initialImage forState:UIControlStateNormal];
        [self.tempSlider setThumbImage:initialImage forState:UIControlStateHighlighted];

        //correct thumbImage positioning
        Method originalThumbRect = class_getInstanceMethod(NSClassFromString(@"MPVolumeSlider"),
                                                           @selector(thumbRectForBounds:trackRect:value:));
        Method newThumbRect = class_getInstanceMethod([CustomizedSlider class],
                                                      @selector(thumbRectForBounds:trackRect:value:));
        method_exchangeImplementations(originalThumbRect, newThumbRect);

        //start updating image
        [DAAnisotropicImage startAnisotropicUpdatesWithHandler:^(UIImage *image) {
            [self.tempSlider setThumbImage:image forState:UIControlStateNormal];
            [self.tempSlider  setThumbImage:image forState:UIControlStateHighlighted];
        }]; 
    }
}

[self.volumeView removeFromSuperview];
[self.view addSubview:volumeView];

}

Hopefully using method_exchangeImplementations passes the app store submission.