Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Workaround an annoying bug with iOS 7.1 where custom track and progress images for UIProgressView gets ignored
//
// JEProgressView.h
//
//
// Created by John Rommel Estropia on 2014/03/11.
// Copyright (c) 2014 John Rommel Estropia.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <UIKit/UIKit.h>
// iOS 7.1 bugfix
// http://stackoverflow.com/questions/22311516/uiprogressview-custom-track-and-progress-images-in-ios-7-1
@interface JEProgressView : UIProgressView
@end
//
// JEProgressView.m
//
//
// Created by John Rommel Estropia on 2014/03/11.
// Copyright (c) 2014 John Rommel Estropia.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "JEProgressView.h"
@interface JEProgressView ()
@property (nonatomic, weak) UIImageView *trackImageView;
@property (nonatomic, weak) UIImageView *progressImageView;
@end
@implementation JEProgressView
#pragma mark - NSObject
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setupProgressView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self setupProgressView];
}
return self;
}
#pragma mark - UIView
- (void)layoutSubviews
{
[super layoutSubviews];
UIImageView *trackImageView = self.trackImageView;
UIImageView *progressImageView = self.progressImageView;
if (!trackImageView || !progressImageView)
{
return;
}
CGRect bounds = self.bounds;
CGFloat boundsTop = CGRectGetMinY(bounds);
UIImage *trackImage = self.trackImage;
if (trackImage)
{
CGRect trackFrame = trackImageView.frame;
CGFloat trackHeight = trackImage.size.height;
trackImageView.frame = (CGRect){
.origin.x = CGRectGetMinX(trackFrame),
.origin.y = (boundsTop
+ ((CGRectGetHeight(bounds) - trackHeight) * 0.5f)),
.size.width = CGRectGetWidth(trackFrame),
.size.height = trackHeight
};
}
UIImage *progressImage = self.progressImage;
if (progressImage)
{
CGRect progressFrame = progressImageView.frame;
CGFloat progressHeight = progressImage.size.height;
progressImageView.frame = (CGRect){
.origin.x = CGRectGetMinX(progressFrame),
.origin.y = (boundsTop
+ ((CGRectGetHeight(bounds) - progressHeight) * 0.5f)),
.size.width = CGRectGetWidth(progressFrame),
.size.height = progressHeight
};
}
}
#pragma mark - UIProgressView
- (void)setProgressImage:(UIImage *)progressImage
{
[super setProgressImage:progressImage];
self.progressImageView.image = progressImage;
}
- (void)setTrackImage:(UIImage *)trackImage
{
[super setTrackImage:trackImage];
self.trackImageView.image = trackImage;
}
#pragma mark - private
- (void)setupProgressView
{
if ([self compareVersionString:[UIDevice currentDevice].systemVersion
withVersionString:@"7.1"] == NSOrderedAscending)
{
return;
}
NSArray *subviews = self.subviews;
if ([subviews count] != 2)
{
return;
}
for (UIView *subview in subviews)
{
if (![subview isKindOfClass:[UIImageView class]])
{
return;
}
}
self.trackImageView = subviews[0];
self.progressImageView = subviews[1];
self.trackImageView.image = self.trackImage;
self.progressImageView.image = self.progressImage;
}
- (NSComparisonResult)compareVersionString:(NSString *)versionString1
withVersionString:(NSString *)versionString2
{
NSArray *components1 = [versionString1 componentsSeparatedByString:@"."];
NSArray *components2 = [versionString2 componentsSeparatedByString:@"."];
NSUInteger components1Count = [components1 count];
NSUInteger components2Count = [components2 count];
NSUInteger partCount = MAX(components1Count, components2Count);
for (NSInteger part = 0; part < partCount; ++part)
{
if (part >= components1Count)
{
return NSOrderedAscending;
}
if (part >= components2Count)
{
return NSOrderedDescending;
}
NSString *part1String = components1[part];
NSString *part2String = components2[part];
NSInteger part1 = [part1String integerValue];
NSInteger part2 = [part2String integerValue];
if (part1 > part2)
{
return NSOrderedDescending;
}
if (part1 < part2)
{
return NSOrderedAscending;
}
}
return NSOrderedSame;
}
@end
Owner

JohnEstropia commented Mar 11, 2014

Workaround an annoying bug with iOS 7.1 where custom track and progress images for UIProgressView gets ignored.

http://openradar.io/16113307
http://stackoverflow.com/questions/22311516/uiprogressview-custom-track-and-progress-images-in-ios-7-1

I used these files for 7.1 but couldn't solve issue for me...

Solved issue..But I need progress bar with round corner

Hi John,

self.tintColor = [UIColor clearColor];

this should be added in the contructors under [self setupProgressView];

Otherwise the default progress indicator can overlay the graphic one on refreshes of the UI.

Actually no, should be done in the setProgressImage...sorry.

mrga commented Mar 21, 2014

Good job... it's working like a charm.
What are Terms of Use for this JEProgressView?

RyoAbe commented Mar 25, 2014

What is license this JEProgressView for commercial use?

JEProgressViewを商用利用させていただきたいのですが、その場合のライセンスを教えて頂けますでしょうか?

mcmatan commented Mar 25, 2014

Thanks this is great

Owner

JohnEstropia commented Mar 27, 2014

@httpsgithub
I haven't tested this, but does the default UIProgressView ignore tintColor when using custom images? If so I'll update the code. Our project clears out tintColor explicitly so I didn't notice.

@mrga
I'm intending to add this to my JEToolkit repository which uses MIT license. I added the license statement in the .h and .m files for now.

@RyoAbe
MITライセンスです。.hと.mに入れておきました。

@JohnEstropia
It works,but not works perfectly.
Here is a problem I met:
Present a JEProgressView on a controller's view.Then show a alertview (or a new window). The JEProgressView's apperance changes.progressTintColor turns to blue. (Sorry about my poor English,hope you can catch my meaning)

It seems (in my trial) that it doesn't work when setting a progressview up in a storyboard - the setProgressImage/TrackImage methods don't get called. If I set it up in code, those methods get called. (And I have changed the class of the progressView in the storyboard to the JEProgressView)

Cheers for your work on this!!

Owner

JohnEstropia commented Apr 18, 2014

@JackTheNoob
as @httpsgithub mentioned above, you seem to also need to set
self.tintColor = [UIColor clearColor];
so your image doesn't turn blue. I'd automatically set the tintColor to clearColor if the images are not null, but I don't want to change the behavior of the original UIProgressView.

@mtancock
Probably because images in storyboards are set straight within -[initWithCoder:]. You did raise a common use case so I'll include a fix for this.

Problem: AlertView drops custom image from JEProgressView's ProgressImage and change it on default values (plane color). By the way TrackImage is ok.

Hi,

thanks for this fix. It totally fits my needs in a project.
Could you explain, why you calculate the origin on the y-axis of the image views the way you are doing it? With your original Code, the two imageViews will have an origin of -7.25 using images with a height of 17px, cause the heigth of the UIProgressView itself is 2,5px, even though I set a frame with a height of 17px.

When I change the line

.origin.y = (boundsTop + ((CGRectGetHeight(bounds) - trackHeight) * 0.5f)),

to

.origin.y = CGRectGetMinY(trackFrame),

the progress image view is positioned as expected. (I do not use an image for the track)

Regards
Oliver

Owner

JohnEstropia commented May 11, 2014

@oklimberg: My computation makes it so that the imageViews are vertically centered within the parent UIProgressView.

works great.

Note: height of progressView is still set to 2., so remember to set progressBar.clipsToBounds=NO

berikv commented Dec 8, 2014

Why not just

- (void)drawRect:(CGRect)rect {
    double progress = MIN(1, MAX(0, self.progress));

    [self.progressBackgroundImage drawInRect:rect];

    CGRect progressFrame = rect;
    progressFrame.size.width = round(rect.size.width * progress);

    [self.progressImage drawInRect:progressFrame];
}

and not subclass UIProgressView?

karnakar commented Feb 6, 2015

Hi,
I have been searching for the same solution for a long time, thanks. Can i make progress view round cornered at the corners.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment