19

I have tried many methods to implement a regular UISlider and control the device volume, but it's all Native-C functions which results in many untraceable bugs.

I tried the MPVolumeView it works like charm, it even controls the device volume even after you close the app, just like the iPod app.

My question is, is there anyway to customize the MPVolumeView with specific colors and images, just like UISlider?

NOTE: I want a legal method without using private undocumented APIs.

UPDATE
As per @Alexsander Akers answer, since the sub views are hidden in MPVolumeView I had to cycle through subviews, get the UISlider and customize it, here is the code.

IBOutlet UISlider *volumeSlider;   //defined in <class.h> and connected to a UISlider in Interface Builder

-(void) viewDidLoad {
     ....
     [self setCustomSlider];
     ....
}

-(void) setCustomSlider{
     MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame:[volumeSlider frame]] autorelease];
     NSArray *tempArray = volumeView.subviews;

     for (id current in tempArray){
           if ([current isKindOfClass:[UISlider class]]){
                    UISlider *tempSlider = (UISlider *) current;
                    UIImage *img = [UIImage imageNamed:@"trackImage.png"];
                    img = [img stretchableImageWithLeftCapWidth:5.0 topCapHeight:0];
                    [tempSlider setMinimumTrackImage:img forState:UIControlStateNormal];

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

           } 
    }
    [volumeSlider removeFromSuperview];
    [self.view addSubview:volumeView];
 }
mohdajami
  • 9,604
  • 3
  • 32
  • 53
  • Well done. Nice job updating your question. – Michael Morrison Feb 05 '11 at 01:14
  • 5
    Just out of curiosity, was this accepted in the App Store? – sooper Feb 24 '12 at 00:25
  • @sooper very late reply, sorry. Unfortunately, I didn't continue this app and never submitted it to App Store. But from personal experience, I have seen many tutorials of modifying the original components and they were accepted. – mohdajami Jun 27 '12 at 08:32
  • 1
    Note that in iOS 6, there are built-in methods for customizing the MPVolumeView slider, similar to the methods for UISlider – coco Dec 17 '12 at 18:09

5 Answers5

10

You could try cycling through its subviews and look for a UISlider subclass?

Alexsander Akers
  • 15,967
  • 12
  • 58
  • 83
  • 1
    In the end that's exactly what I used, Just for clarity I will update the question with the code. I hope Apple don't reject the app for that. – mohdajami Sep 29 '10 at 10:03
8

Since iOS 5.0 you can use UIAppearance on a UISlider, even when part of MPVolumeView.

Anywhere in your codebase:

[[UISlider appearanceWhenContainedIn:[MPVolumeView class], nil] setMinimumTrackImage:[[UIImage imageNamed:@"nowplaying_bar_full.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(5, 25, 5, 25)] forState:UIControlStateNormal];
[[UISlider appearanceWhenContainedIn:[MPVolumeView class], nil] setMaximumTrackImage:[[UIImage imageNamed:@"nowplaying_bar_empty.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(5, 25, 5, 25)] forState:UIControlStateNormal];
[[UISlider appearanceWhenContainedIn:[MPVolumeView class], nil] setThumbImage:[UIImage imageNamed:@"nowplaying_player_nob.png"] forState:UIControlStateNormal];

Here a list of some of the other classes that can be implemented using UIAppearance: https://gist.github.com/mattt/5135521

cescofry
  • 3,706
  • 3
  • 26
  • 22
3

There are now ways to accomplish this, simply use:

– setMaximumVolumeSliderImage:forState:
– setMinimumVolumeSliderImage:forState:
– setVolumeThumbImage:forState:

Which are slightly different method names than the ones for the vanilla UISlider.

This prevents you from having to cycle through the views and potentially have something break in the future as Apple changes things.

ekinnear
  • 437
  • 2
  • 10
1

Answer in Swift:

func customSlider() {
        let temp = mpVolView.subviews
        for current in temp {
            if current.isKind(of: UISlider.self) {
                let tempSlider = current as! UISlider
                tempSlider.minimumTrackTintColor = .yellow
                tempSlider.maximumTrackTintColor = .blue
            }
        }
    }

Result:

enter image description here

Adam
  • 1,776
  • 1
  • 17
  • 28
-1

Try using a Notification, but it looks like Apple is denying them.


[EDIT]

Try this.

Community
  • 1
  • 1
Stephen Furlani
  • 6,794
  • 4
  • 31
  • 60