Skip to content

Commit ea13ff3

Browse files
Fixed Issue #28
The UINavigationController progress bar now responds rotations of the navigation controller.
1 parent 0268f9f commit ea13ff3

File tree

3 files changed

+86
-24
lines changed

3 files changed

+86
-24
lines changed

Classes/NavigationController/UINavigationController+M13ProgressViewBar.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,7 @@
3434
- (void)finishProgress;
3535
/**Remove the progress bar from the display.*/
3636
- (void)cancelProgress;
37+
/**Wether or not the progress bar is showing.*/
38+
- (BOOL)isShowingProgressBar;
3739

3840
@end

Classes/NavigationController/UINavigationController+M13ProgressViewBar.m

Lines changed: 84 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
static char progressViewKey;
1717
static char indeterminateKey;
1818
static char indeterminateLayerKey;
19+
static char isShowingProgressKey;
1920

2021
@implementation UINavigationController (M13ProgressViewBar)
2122

@@ -104,6 +105,7 @@ - (void)finishProgress
104105
[progressView removeFromSuperview];
105106
progressView.alpha = 1;
106107
[self setTitle:nil];
108+
[self setIsShowingProgressBar:NO];
107109
}];
108110
}];
109111
});
@@ -122,6 +124,7 @@ - (void)cancelProgress
122124
[progressView removeFromSuperview];
123125
progressView.alpha = 1;
124126
[self setTitle:nil];
127+
[self setIsShowingProgressBar:NO];
125128
}];
126129
});
127130
}
@@ -136,43 +139,76 @@ - (void)showProgress
136139
[UIView animateWithDuration:.1 animations:^{
137140
progressView.alpha = 1;
138141
}];
142+
143+
[self setIsShowingProgressBar:YES];
139144
}
140145

141146
- (void)updateProgress
147+
{
148+
[self updateProgressWithInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation];
149+
}
150+
151+
- (void)updateProgressWithInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
142152
{
143153
//Create the progress view if it doesn't exist
144154
UIView *progressView = [self getProgressView];
145-
if(!progressView)
155+
if(!progressView)
146156
{
147-
float y = self.navigationBar.frame.size.height - 2.5;
148-
progressView = [[UIView alloc] initWithFrame:CGRectMake(0, y, 0, 2.5)];
157+
progressView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 2.5)];
149158
progressView.backgroundColor = self.navigationBar.tintColor;
150159
progressView.clipsToBounds = YES;
151160
[self setProgressView:progressView];
152-
[self.navigationBar addSubview:progressView];
153161
}
154-
if (progressView.superview == nil) {
162+
163+
//Calculate the frame of the navigation bar, based off the orientation.
164+
CGSize screenSize = [UIScreen mainScreen].bounds.size;
165+
CGFloat width = 0.0;
166+
CGFloat height = 0.0;
167+
//Calculate the width of the screen
168+
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
169+
//Use the maximum value
170+
width = MAX(screenSize.width, screenSize.height);
171+
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
172+
height = 32.0; //Hate hardcoding values, but autolayout doesn't work, and cant retreive the new height until after the animation completes.
173+
} else {
174+
height = 44.0; //Hate hardcoding values, but autolayout doesn't work, and cant retreive the new height until after the animation completes.
175+
}
176+
} else {
177+
//Use the minimum value
178+
width = MIN(screenSize.width, screenSize.height);
179+
height = 44.0; //Hate hardcoding values, but autolayout doesn't work, and cant retreive the new height until after the animation completes.
180+
}
181+
182+
//Check if the progress view is in its superview and if we are showing the bar.
183+
if (progressView.superview == nil && [self isShowingProgressBar]) {
155184
[self.navigationBar addSubview:progressView];
156185
}
157186

187+
//Layout
158188
if (![self getIndeterminate]) {
159-
//Calculate the width of the progress view
160-
float maxWidth = self.navigationBar.frame.size.width;
161-
float progressWidth = maxWidth * [self getProgress];
189+
//Calculate the width of the progress view;
190+
float progressWidth = width * [self getProgress];
162191
//Set the frame of the progress view
163-
CGRect progressFrame = progressView.frame;
164-
progressFrame.size.width = progressWidth;
165-
progressView.frame = progressFrame;
192+
progressView.frame = CGRectMake(0, height - 2.5, progressWidth, 2.5);
166193
} else {
167194
//Calculate the width of the progress view
168-
float maxWidth = self.navigationBar.frame.size.width;
169-
CGRect progressFrame = progressView.frame;
170-
progressFrame.size.width = maxWidth;
171-
progressView.frame = progressFrame;
195+
progressView.frame = CGRectMake(0, height - 2.5, width, 2.5);
172196
}
197+
198+
}
199+
200+
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
201+
{
202+
[self updateProgressWithInterfaceOrientation:toInterfaceOrientation];
203+
[self drawIndeterminateWithInterfaceOrientation:toInterfaceOrientation];
173204
}
174205

175206
- (void)drawIndeterminate
207+
{
208+
[self drawIndeterminateWithInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation];
209+
}
210+
211+
- (void)drawIndeterminateWithInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
176212
{
177213
if ([self getIndeterminate]) {
178214
//Get the indeterminate layer
@@ -183,6 +219,25 @@ - (void)drawIndeterminate
183219
[self setIndeterminateLayer:indeterminateLayer];
184220
}
185221

222+
//Calculate the frame of the navigation bar, based off the orientation.
223+
CGSize screenSize = [UIScreen mainScreen].bounds.size;
224+
CGFloat width = 0.0;
225+
CGFloat height = 0.0;
226+
//Calculate the width of the screen
227+
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
228+
//Use the maximum value
229+
width = MAX(screenSize.width, screenSize.height);
230+
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
231+
height = 32.0; //Hate hardcoding values, but autolayout doesn't work, and cant retreive the new height until after the animation completes.
232+
} else {
233+
height = 44.0; //Hate hardcoding values, but autolayout doesn't work, and cant retreive the new height until after the animation completes.
234+
}
235+
} else {
236+
//Use the minimum value
237+
width = MIN(screenSize.width, screenSize.height);
238+
height = 44.0; //Hate hardcoding values, but autolayout doesn't work, and cant retreive the new height until after the animation completes.
239+
}
240+
186241
//Create the pattern image
187242
CGFloat stripeWidth = 2.5;
188243
//Start the image context
@@ -217,21 +272,21 @@ - (void)drawIndeterminate
217272
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
218273
UIGraphicsEndImageContext();
219274
//Set the background of the progress layer
220-
indeterminateLayer.backgroundColor = [UIColor colorWithPatternImage:image].CGColor;\
275+
indeterminateLayer.backgroundColor = [UIColor colorWithPatternImage:image].CGColor;
221276

222277
//remove any indeterminate layer animations
223278
[indeterminateLayer removeAllAnimations];
224279
//Set the indeterminate layer frame and add to the sub view
225-
indeterminateLayer.frame = CGRectMake(0, 0, self.navigationBar.frame.size.width + (4 * 2.5), 2.5);
280+
indeterminateLayer.frame = CGRectMake(0, 0, width + (4 * 2.5), 2.5);
226281
UIView *progressView = [self getProgressView];
227282
[progressView.layer addSublayer:indeterminateLayer];
228283
//Add the animation
229284
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
230285
animation.duration = .1;
231286
animation.repeatCount = HUGE_VALF;
232287
animation.removedOnCompletion = YES;
233-
animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(- (2 * 2.5) + (self.navigationBar.frame.size.width / 2.0), 2.5 / 2.0)];
234-
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0 + (self.navigationBar.frame.size.width / 2.0), 2.5 / 2.0)];
288+
animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(- (2 * 2.5) + (width / 2.0), 2.5 / 2.0)];
289+
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0 + (width / 2.0), 2.5 / 2.0)];
235290
[indeterminateLayer addAnimation:animation forKey:@"position"];
236291
} else {
237292
CALayer *indeterminateLayer = [self getIndeterminateLayer];
@@ -314,15 +369,15 @@ - (void)setProgress:(CGFloat)progress
314369
}
315370
}
316371

317-
- (CGFloat)getProgress
372+
- (void)setIsShowingProgressBar:(BOOL)isShowingProgressBar
318373
{
319-
NSNumber *number = objc_getAssociatedObject(self, &progressKey);
320-
return number.floatValue;
374+
objc_setAssociatedObject(self, &isShowingProgressKey, [NSNumber numberWithBool:isShowingProgressBar], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
321375
}
322376

323-
- (void)setAnimationDuration:(CGFloat)animationDuration
377+
- (CGFloat)getProgress
324378
{
325-
379+
NSNumber *number = objc_getAssociatedObject(self, &progressKey);
380+
return number.floatValue;
326381
}
327382

328383
- (CGFloat)getAnimationDuration
@@ -363,4 +418,9 @@ - (CALayer *)getIndeterminateLayer
363418
return objc_getAssociatedObject(self, &indeterminateLayerKey);
364419
}
365420

421+
- (BOOL)isShowingProgressBar
422+
{
423+
return objc_getAssociatedObject(self, &isShowingProgressKey);
424+
}
425+
366426
@end
Binary file not shown.

0 commit comments

Comments
 (0)