diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac8f968 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so +*.pyc + +# Logs and databases # +###################### +*.log + +# OS generated files # +###################### +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db diff --git a/ATMHud-Info.plist b/ATMHud-Info.plist index 1b2d776..752e48a 100644 --- a/ATMHud-Info.plist +++ b/ATMHud-Info.plist @@ -2,13 +2,6 @@ - UIPrerenderedIcon - - CFBundleIconFiles - - Icon.png - Icon@2x.png - CFBundleDevelopmentRegion English CFBundleDisplayName @@ -17,8 +10,13 @@ ${EXECUTABLE_NAME} CFBundleIconFile + CFBundleIconFiles + + Icon.png + Icon@2x.png + CFBundleIdentifier - ${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -33,5 +31,7 @@ NSMainNibFile MainWindow + UIPrerenderedIcon + diff --git a/ATMHud.h b/ATMHud.h index ebc5476..0888fcc 100644 --- a/ATMHud.h +++ b/ATMHud.h @@ -4,104 +4,132 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import -@class ATMHudView, ATMSoundFX, ATMHudQueueItem; + +#import "ATMProgressLayer.h" // For the style enum + +@class ATMHud, ATMHudQueueItem; +#ifdef ATM_SOUND +@class ATMSoundFX; +#endif @protocol ATMHudDelegate; -typedef enum { +typedef NS_ENUM(NSInteger, ATMHudAccessoryPosition) { ATMHudAccessoryPositionTop = 0, ATMHudAccessoryPositionRight, ATMHudAccessoryPositionBottom, ATMHudAccessoryPositionLeft -} ATMHudAccessoryPosition; - -@interface ATMHud : UIViewController { - CGFloat margin; - CGFloat padding; - CGFloat alpha; - CGFloat appearScaleFactor; - CGFloat disappearScaleFactor; - CGFloat progressBorderRadius; - CGFloat progressBorderWidth; - CGFloat progressBarRadius; - CGFloat progressBarInset; - - CGPoint center; - - BOOL shadowEnabled; - BOOL blockTouches; - BOOL allowSuperviewInteraction; - - NSString *showSound; - NSString *updateSound; - NSString *hideSound; - - id delegate; - ATMHudAccessoryPosition accessoryPosition; - - @private - ATMHudView *__view; - ATMSoundFX *sound; - NSMutableArray *displayQueue; - NSInteger queuePosition; -} - -@property (nonatomic, assign) CGFloat margin; -@property (nonatomic, assign) CGFloat padding; -@property (nonatomic, assign) CGFloat alpha; -@property (nonatomic, assign) CGFloat appearScaleFactor; -@property (nonatomic, assign) CGFloat disappearScaleFactor; -@property (nonatomic, assign) CGFloat progressBorderRadius; -@property (nonatomic, assign) CGFloat progressBorderWidth; -@property (nonatomic, assign) CGFloat progressBarRadius; -@property (nonatomic, assign) CGFloat progressBarInset; - -@property (nonatomic, assign) CGPoint center; - -@property (nonatomic, assign) BOOL shadowEnabled; -@property (nonatomic, assign) BOOL blockTouches; -@property (nonatomic, assign) BOOL allowSuperviewInteraction; - -@property (nonatomic, retain) NSString *showSound; -@property (nonatomic, retain) NSString *updateSound; -@property (nonatomic, retain) NSString *hideSound; - -@property (nonatomic, assign) id delegate; -@property (nonatomic, assign) ATMHudAccessoryPosition accessoryPosition; - -@property (nonatomic, retain) ATMHudView *__view; -@property (nonatomic, retain) ATMSoundFX *sound; -@property (nonatomic, retain) NSMutableArray *displayQueue; -@property (nonatomic, assign) NSInteger queuePosition; - -+ (NSString *)buildInfo; - -- (id)initWithDelegate:(id)hudDelegate; - -- (void)setCaption:(NSString *)caption; -- (void)setImage:(UIImage *)image; -- (void)setActivity:(BOOL)activity; -- (void)setActivityStyle:(UIActivityIndicatorViewStyle)activityStyle; -- (void)setFixedSize:(CGSize)fixedSize; -- (void)setProgress:(CGFloat)progress; +}; + +// See DemoViewController for blockDelegate usage +typedef NS_ENUM(NSInteger, ATMHudAction) { + ATMHudActionUserDidTapHud, // actual HUD + ATMHudActionUserDidTapOutsideHud, // somewhere else in the view + + ATMHudActionWillAppear, + ATMHudActionDidAppear, + ATMHudActionWillUpdate, + ATMHudActionDidUpdate, + ATMHudActionWillDisappear, + ATMHudActionDidDisappear, + + // add your own functionality to the blockDelegate, for instance to dismiss an action sheet + ATMHudActionUsrAction1, + ATMHudActionUsrAction2, + ATMHudActionUsrAction3, + ATMHudActionUsrAction4, +}; + + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^ATMblockDelegate)(ATMHudAction msg, ATMHud *hud); + +@interface ATMHud : UIViewController +// Properties persist from show to show +@property (nonatomic, assign) CGFloat margin; // default 10.0f +@property (nonatomic, assign) CGFloat padding; // default 10.0f +@property (nonatomic, assign) CGFloat alpha; // default 0.8f +@property (nonatomic, assign) CGFloat gray; // default 0.8f +@property (nonatomic, assign) CGFloat animateDuration; // default 0.1f +@property (nonatomic, assign) CGFloat progressBorderRadius; // default 8.0f +@property (nonatomic, assign) ATMHudProgressStyle progressStyle; // default ATMHudProgressStyleBar. Must set before the HudView is created. +@property (nonatomic, assign) CGFloat progressBorderWidth; // default 2.0f +@property (nonatomic, assign) CGFloat progressRadius; // default 5.0f +@property (nonatomic, assign) CGFloat progressInset; // default 3.0f +@property (nonatomic, assign) CGFloat appearScaleFactor; // default 0.8; +@property (nonatomic, assign) CGFloat disappearScaleFactor; // default 5.0f +@property (nonatomic, assign) NSTimeInterval minShowTime; // default 0 sec - do not hide even if told to until this much time elapses + // to insure HUD visible at least this long + // set "minShowTime" before "show" , then send show, then send hide +@property (nonatomic, assign) CGPoint center; // default {0, 0} - clients can place the HUD center above or below the real view centerpoint +@property (nonatomic, assign) BOOL shadowEnabled; // default NO +@property (nonatomic, assign) BOOL usesParallax; // default YES +@property (nonatomic, assign) CGFloat backgroundAlpha; // default 0.0f; applied as [UIColor colorWithWhite:backgroundAlpha alpha:backgroundAlpha]; +@property (nonatomic, strong) UIColor *hudBackgroundColor; // default is a light slightly blue color + +@property (nonatomic, weak) id delegate; // traditional delegate +@property (nonatomic, copy) ATMblockDelegate blockDelegate; // block delegate +@property (nonatomic, copy, nullable) void (^convenienceBlock)(); // ATMHud will keep this block around for you +#ifdef ATM_SOUND +@property (nonatomic, strong) ATMSoundFX *sound; +#endif +@property (nonatomic, assign, readonly) NSUInteger queuePosition; // item which is showing + ++ (NSString *)version; + +- (instancetype)initWithDelegate:(id)hudDelegate; + +// These variables are reset after each hide +- (void)setCaption:(NSString *)caption; // Reset to @"" after each hide +- (void)setImage:(UIImage * _Nullable )image; // Reset to nil +- (void)setActivity:(BOOL)activity; // Reset to NO +- (void)setActivityStyle:(UIActivityIndicatorViewStyle)activityStyle; // Reset to UIActivityIndicatorViewStyleWhite +- (void)setAccessoryPosition:(ATMHudAccessoryPosition)pos; // Reset to ATMHudAccessoryPositionBottom +- (void)setFixedSize:(CGSize)fixedSize; // Reset to CGSizeZero +- (void)setProgress:(CGFloat)progress; // Reset to 0 +- (void)setCenter:(CGPoint)pt; // Reset to CGPointZero +- (void)setBlockTouches:(BOOL)val; // Reset to NO +- (void)setAllowSuperviewInteraction:(BOOL)val; // Reset to NO +#ifdef ATM_SOUND +- (void)setShowSound:(NSString *)sound; // Reset to nil +- (void)setUpdateSound:(NSString *)sound; // Reset to nil +- (void)setHideSound:(NSString *)sound; // Reset to nil +#endif + +- (ATMHudAccessoryPosition)accessoryPosition; +- (BOOL)allowSuperviewInteraction; +#ifdef ATM_SOUND +- (NSString *)showSound; +- (NSString *)updateSound; +- (NSString *)hideSound; +#endif - (void)addQueueItem:(ATMHudQueueItem *)item; -- (void)addQueueItems:(NSArray *)items; +- (void)addQueueItems:(NSArray *)items; - (void)clearQueue; -- (void)startQueue; +- (void)startQueueInView:(UIView *)view; - (void)showNextInQueue; -- (void)showQueueAtIndex:(NSInteger)index; -- (void)show; +- (void)showInView:(UIView *)view; - (void)update; -- (void)hide; -- (void)hideAfter:(NSTimeInterval)delay; +- (void)hide; // Ordered removal. Note: now removes the hudView from its superview +- (void)unloadView; // Blunt force removal. Do not call hide. + +- (void)show __attribute__((deprecated)); // use showInView +- (void)hideAfter:(NSTimeInterval)delay __attribute__((deprecated)); // set "minShowTime" before "show" , then show, then send "hide" + +#ifdef ATM_SOUND - (void)playSound:(NSString *)soundPath; +#endif @end + +NS_ASSUME_NONNULL_END diff --git a/ATMHud.m b/ATMHud.m index 4c29853..46a841d 100644 --- a/ATMHud.m +++ b/ATMHud.m @@ -4,187 +4,314 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ -#import "ATMHud.h" #import +#ifdef ATM_SOUND #import +#endif +#import "ATMHud.h" #import "ATMHudView.h" -#import "ATMProgressLayer.h" #import "ATMHudDelegate.h" -#import "ATMSoundFX.h" #import "ATMHudQueueItem.h" +#ifdef ATM_SOUND +#import "ATMSoundFX.h" +#endif + +#define VERSION @"atomHUD 4.0.0 • 2016-02-15" + +#define SHADOW_OPACITY 0.4f + +@interface ATMHud () +@property (nonatomic, assign) NSUInteger queuePosition; +@property (nonatomic, assign) ATMHudAccessoryPosition accessoryPosition; +@property (nonatomic, assign) BOOL blockTouches; +@property (nonatomic, assign) BOOL allowSuperviewInteraction; +#ifdef ATM_SOUND +@property (nonatomic, copy) NSString *showSound; +@property (nonatomic, copy) NSString *updateSound; +@property (nonatomic, copy) NSString *hideSound; +#endif -@interface ATMHud (Private) -- (void)construct; @end + @implementation ATMHud -@synthesize margin, padding, alpha, appearScaleFactor, disappearScaleFactor, progressBorderRadius, progressBorderWidth, progressBarRadius, progressBarInset; -@synthesize delegate, accessoryPosition; -@synthesize center; -@synthesize shadowEnabled, blockTouches, allowSuperviewInteraction; -@synthesize showSound, updateSound, hideSound; -@synthesize __view, sound, displayQueue, queuePosition; - -- (id)init { +{ + ATMHudView *hudView; + NSMutableArray *displayQueue; + NSDate *minShowDate; +} + ++ (NSString *)version +{ + return VERSION; +} + +- (instancetype)init +{ if ((self = [super init])) { - [self construct]; + _margin = 20.0f; // DFH: was 10 + _padding = 10.0f; + _alpha = 0.95f; // DFH: originally 0.7 + _gray = 0.1f; // DFH: originally 0.0 + _animateDuration = 0.1f; + _progressStyle = ATMHudProgressStyleBar; + _progressBorderRadius = 4.0f; // DFH: was 8 + _progressBorderWidth = 0.5; // DFH: was 2 + _progressRadius = 2.0f; // DFH: was 5 + _progressInset = 3.0f; // DFH: was 3 + _appearScaleFactor = 0.8; // DFH: originally 1.4f + _disappearScaleFactor = 0.8; // DFH: originally 1.4f + _backgroundAlpha = 0.15; + _usesParallax = YES; + _hudBackgroundColor = [[UIColor alloc] initWithRed:.98 green:.99 blue:1.0 alpha:_alpha]; // DFH was [UIColor colorWithWhite:_hud.gray alpha:_hud.alpha] + +#if 0 // these default to these + _minShowTime = 0; + _center = CGPointZero; + _blockTouches = NO; + _allowSuperviewInteraction = NO; + _removeViewWhenHidden = NO; + _shadowEnabled = NO; + _queuePosition = 0; +#endif + hudView = [[ATMHudView alloc] initWithFrame:CGRectZero andController:self]; + hudView.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | + UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleBottomMargin | + UIViewAutoresizingFlexibleLeftMargin ); + hudView.hudBackgroundColor = _hudBackgroundColor; + [hudView reset]; // actually sets many of our variables } return self; } -- (id)initWithDelegate:(id)hudDelegate { - if ((self = [super init])) { - delegate = hudDelegate; - [self construct]; +- (instancetype)initWithDelegate:(id)hudDelegate +{ + if ((self = [self init])) { + _delegate = hudDelegate; } return self; } -- (void)loadView { +- (void)dealloc +{ + //NSLog(@"ATM HUD DEALLOC..."); + [self unloadView]; + //NSLog(@"...ATM HUD DEALLOC"); +} + +- (void)unloadView +{ + assert([NSThread isMainThread]); + if(self.view.window != nil) { + //[hudView removeFromSuperview]; // TODO: this should be redundant, since its a child view of the ATMHud view" + [self.view removeFromSuperview]; + } +} + +- (void)loadView +{ UIView *base = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - base.backgroundColor = [UIColor clearColor]; - base.autoresizingMask = (UIViewAutoresizingFlexibleWidth | - UIViewAutoresizingFlexibleHeight); - base.userInteractionEnabled = NO; - [base addSubview:__view]; - + base.backgroundColor = [UIColor colorWithWhite:_backgroundAlpha alpha:_backgroundAlpha]; + base.autoresizingMask = (UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight); + base.userInteractionEnabled = NO; + [base addSubview:hudView]; + self.view = base; - [base release]; } -- (void)viewDidLoad { +- (void)viewDidLoad +{ [super viewDidLoad]; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ return YES; } -- (void)didReceiveMemoryWarning { +- (void)didReceiveMemoryWarning +{ [super didReceiveMemoryWarning]; } -- (void)viewDidUnload { +- (void)viewDidUnload +{ [super viewDidUnload]; } -- (void)dealloc { - [sound release]; - [__view release]; - [displayQueue release]; - - [showSound release]; - [updateSound release]; - [hideSound release]; - - [super dealloc]; -} - -+ (NSString *)buildInfo { - return @"atomHUD 1.2 • 2011-03-01"; -} - #pragma mark - #pragma mark Overrides -- (void)setAppearScaleFactor:(CGFloat)value { - if (value == 0) { - value = 0.01; + +- (void)setAppearScaleFactor:(CGFloat)value +{ + if (!isnormal(value)) { + value = 0.01f; } - appearScaleFactor = value; + _appearScaleFactor = value; } -- (void)setDisappearScaleFactor:(CGFloat)value { - if (value == 0) { - value = 0.01; +- (void)setDisappearScaleFactor:(CGFloat)value +{ + if (!isnormal(value)) { + value = 0.01f; } - disappearScaleFactor = value; + _disappearScaleFactor = value; } -- (void)setAlpha:(CGFloat)value { - alpha = value; +- (void)setAlpha:(CGFloat)value +{ + _alpha = value; [CATransaction begin]; [CATransaction setDisableActions:YES]; - __view.backgroundLayer.backgroundColor = [UIColor colorWithWhite:0.0 alpha:value].CGColor; + hudView.backgroundLayer.backgroundColor = [UIColor colorWithWhite:_gray alpha:value].CGColor; [CATransaction commit]; } -- (void)setShadowEnabled:(BOOL)value { - shadowEnabled = value; - if (shadowEnabled) { - __view.layer.shadowOpacity = 0.4; - } else { - __view.layer.shadowOpacity = 0.0; - } +- (void)setGray:(CGFloat)value +{ + _gray = value; + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + hudView.backgroundLayer.backgroundColor = [UIColor colorWithWhite:_gray alpha:_alpha].CGColor; + [CATransaction commit]; +} + +- (void)setCenter:(CGPoint)pt +{ + _center = pt; + hudView.center = pt; +} + +- (void)setShadowEnabled:(BOOL)value +{ + _shadowEnabled = value; + hudView.layer.shadowOpacity = value ? SHADOW_OPACITY :0.0f; +} + +- (void)setHudBackgroundColor:(UIColor *)color { + _hudBackgroundColor = color; + hudView.backgroundColor = _hudBackgroundColor; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"HUD: caption=%@", hudView.caption]; } #pragma mark - #pragma mark Property forwards -- (void)setCaption:(NSString *)caption { - __view.caption = caption; + +- (void)setCaption:(NSString *)caption +{ + hudView.caption = caption; } -- (void)setImage:(UIImage *)image { - __view.image = image; +- (void)setImage:(UIImage *)image +{ + hudView.image = image; } -- (void)setActivity:(BOOL)activity { - __view.showActivity = activity; +#if 1 +- (void)setActivity:(BOOL)activity +{ + hudView.showActivity = activity; if (activity) { - [__view.activity startAnimating]; + [hudView.activity startAnimating]; + hudView.activity.alpha = 0; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^ + { + // Workaround for bug where Apple ignores the color property + [self changeColor]; + } ); } else { - [__view.activity stopAnimating]; + [hudView.activity stopAnimating]; } } -- (void)setActivityStyle:(UIActivityIndicatorViewStyle)activityStyle { - __view.activityStyle = activityStyle; - if (activityStyle == UIActivityIndicatorViewStyleWhiteLarge) { - __view.activitySize = CGSizeMake(37, 37); +- (void)changeColor +{ + hudView.activity.color = [UIColor blackColor]; + [UIView animateWithDuration:.250+_animateDuration animations: ^{ hudView.activity.alpha = 1; }]; +} +#else // in case need to test some other better solution +- (void)setActivity:(BOOL)activity +{ + hudView.showActivity = activity; + if (activity) { +assert([NSThread isMainThread]); +hudView.activity.color = [UIColor colorWithRed:252.0/255.0 green:113.0/255.0 blue:9.0/255.0 alpha:1.0]; + [hudView.activity startAnimating]; } else { - __view.activitySize = CGSizeMake(20, 20); + [hudView.activity stopAnimating]; } } +- (void)changeColor +{ + NSLog(@"?????!!!"); +} -- (void)setFixedSize:(CGSize)fixedSize { - __view.fixedSize = fixedSize; +#endif + +- (void)setActivityStyle:(UIActivityIndicatorViewStyle)activityStyle +{ + hudView.activityStyle = activityStyle; + hudView.activitySize = activityStyle == UIActivityIndicatorViewStyleWhiteLarge ? CGSizeMake(37, 37) : CGSizeMake(20, 20); +} + +- (void)setFixedSize:(CGSize)fixedSize +{ + hudView.fixedSize = fixedSize; } -- (void)setProgress:(CGFloat)progress { - __view.progress = progress; +- (void)setProgress:(CGFloat)progress +{ + if (progress < 0) progress = 0; + else + if (progress > 1.0f) progress = 1; - [__view.progressLayer setTheProgress:progress]; - [__view.progressLayer setNeedsDisplay]; + hudView.progress = progress; } #pragma mark - #pragma mark Queue -- (void)addQueueItem:(ATMHudQueueItem *)item { + +- (void)addQueueItem:(ATMHudQueueItem *)item +{ + if(!displayQueue) { + displayQueue = [NSMutableArray arrayWithCapacity:4]; + } [displayQueue addObject:item]; } -- (void)addQueueItems:(NSArray *)items { +- (void)addQueueItems:(NSArray *)items +{ [displayQueue addObjectsFromArray:items]; } -- (void)clearQueue { +- (void)clearQueue +{ [displayQueue removeAllObjects]; } -- (void)startQueue { - queuePosition = 0; - if (!CGSizeEqualToSize(__view.fixedSize, CGSizeZero)) { - CGSize newSize = __view.fixedSize; +- (void)startQueueInView:(UIView *)view +{ + _queuePosition = 0; + if (!CGSizeEqualToSize(hudView.fixedSize, CGSizeZero)) { + CGSize newSize = hudView.fixedSize; CGSize targetSize; ATMHudQueueItem *queueItem; - for (int i = 0; i < [displayQueue count]; i++) { - queueItem = [displayQueue objectAtIndex:i]; + for (NSUInteger i = 0; i < [displayQueue count]; i++) { + queueItem = displayQueue[i]; - targetSize = [__view calculateSizeForQueueItem:queueItem]; + targetSize = [hudView calculateSizeForQueueItem:queueItem]; if (targetSize.width > newSize.width) { newSize.width = targetSize.width; } @@ -194,105 +321,150 @@ - (void)startQueue { } [self setFixedSize:newSize]; } - [self showQueueAtIndex:queuePosition]; + [self showQueueAtIndex:_queuePosition inView:view]; } -- (void)showNextInQueue { - queuePosition++; - [self showQueueAtIndex:queuePosition]; +- (void)showNextInQueue +{ + _queuePosition++; + [self showQueueAtIndex:_queuePosition inView:nil]; } -- (void)showQueueAtIndex:(NSInteger)index { +- (void)showQueueAtIndex:(NSUInteger)index inView:view +{ if ([displayQueue count] > 0) { - queuePosition = index; - if (queuePosition == [displayQueue count]) { + _queuePosition = index; + if (_queuePosition == [displayQueue count]) { [self hide]; return; } - ATMHudQueueItem *item = [displayQueue objectAtIndex:queuePosition]; + ATMHudQueueItem *item = displayQueue[_queuePosition]; - __view.caption = item.caption; - __view.image = item.image; + hudView.caption = item.caption; + hudView.image = item.image; BOOL flag = item.showActivity; - __view.showActivity = flag; + hudView.showActivity = flag; if (flag) { - [__view.activity startAnimating]; + [hudView.activity startAnimating]; + hudView.activity.alpha = 0; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^ + { + // Workaround for bug where Apple ignores the color property + [self changeColor]; + } ); } else { - [__view.activity stopAnimating]; + [hudView.activity stopAnimating]; } - self.accessoryPosition = item.accessoryPosition; + _accessoryPosition = item.accessoryPosition; [self setActivityStyle:item.activityStyle]; - if (queuePosition == 0) { - [__view show]; + if (_queuePosition == 0) { + [self showInView:view]; } else { - [__view update]; + [self update]; } } } #pragma mark - #pragma mark Controlling -- (void)show { - [__view show]; + +- (void)showInView:(UIView *)v +{ + self.view.frame = v.bounds; + + [v addSubview:self.view]; + [self _show]; +} + +- (void)show +{ + [self _show]; +} + +- (void)_show +{ + [self updateHideTime]; + [hudView show]; } -- (void)update { - [__view update]; +- (void)update +{ + [self updateHideTime]; + [hudView update]; } -- (void)hide { - [__view hide]; +- (void)updateHideTime +{ + if (isnormal(_minShowTime)) { + //NSLog(@"NOW %@", [NSDate new]); + minShowDate = [NSDate dateWithTimeIntervalSinceNow:_minShowTime]; + //NSLog(@"LATER %@", minShowDate); + } else { + minShowDate = nil; // just be sure + } } -- (void)hideAfter:(NSTimeInterval)delay { +- (void)hide +{ + _blockTouches = YES; + + NSTimeInterval x = [minShowDate timeIntervalSinceDate:[NSDate date]]; // if minShowDate==nil then x==0 + if (x <= 0 && hudView != nil) { + [hudView hide]; + } else { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, x * NSEC_PER_SEC), dispatch_get_main_queue(), ^ + { + [hudView hide]; + } ); + } +} + +- (void)hideAfter:(NSTimeInterval)delay +{ + _blockTouches = YES; + [self performSelector:@selector(hide) withObject:nil afterDelay:delay]; } #pragma mark - #pragma mark Internal methods -- (void)construct { - margin = padding = 10.0; - alpha = 0.7; - progressBorderRadius = 8.0; - progressBorderWidth = 2.0; - progressBarRadius = 5.0; - progressBarInset = 3.0; - accessoryPosition = ATMHudAccessoryPositionBottom; - appearScaleFactor = disappearScaleFactor = 1.4; - - __view = [[ATMHudView alloc] initWithFrame:CGRectZero andController:self]; - __view.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | - UIViewAutoresizingFlexibleRightMargin | - UIViewAutoresizingFlexibleBottomMargin | - UIViewAutoresizingFlexibleLeftMargin); - - displayQueue = [[NSMutableArray alloc] init]; - queuePosition = 0; - center = CGPointZero; - blockTouches = NO; - allowSuperviewInteraction = NO; -} -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - if (!blockTouches) { +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (!_blockTouches) { + _blockTouches = YES; UITouch *aTouch = [touches anyObject]; if (aTouch.tapCount == 1) { CGPoint p = [aTouch locationInView:self.view]; - if (CGRectContainsPoint(__view.frame, p)) { - if ([(id)self.delegate respondsToSelector:@selector(userDidTapHud:)]) { - [self.delegate userDidTapHud:self]; + if (CGRectContainsPoint(hudView.frame, p)) { + if ([(id)_delegate respondsToSelector:@selector(userDidTapHud:)]) { + [_delegate userDidTapHud:self]; + } + if (_blockDelegate) { + _blockDelegate(ATMHudActionUserDidTapHud, self); + } + } else { + if ([(id)_delegate respondsToSelector:@selector(userDidTapOutsideHud:)]) { + [_delegate userDidTapOutsideHud:self]; + } + if (_blockDelegate) { + _blockDelegate(ATMHudActionUserDidTapOutsideHud, self); } } } + _blockTouches = NO; } } -- (void)playSound:(NSString *)soundPath { - sound = [[ATMSoundFX alloc] initWithContentsOfFile:soundPath]; - [sound play]; +#ifdef ATM_SOUND +- (void)playSound:(NSString *)soundPath +{ + _sound = [[ATMSoundFX alloc] initWithContentsOfFile:soundPath]; + [_sound play]; } +#endif @end diff --git a/ATMHud.podspec b/ATMHud.podspec new file mode 100644 index 0000000..7c407bd --- /dev/null +++ b/ATMHud.podspec @@ -0,0 +1,48 @@ +Pod::Spec.new do |s| + s.name = 'ATMHud' + s.version = '3.0.0' + s.platform = :ios + s.ios.deployment_target = '7.0' + s.license = 'BSD' + s.summary = 'Full featured and flexible HUD framework.' + s.homepage = 'https://github.com/dhoerl/ATMHud' + s.author = { 'Marcel Müller' => 'pool@atomton.net', 'David Hoerl' => 'david.hoerl+git@gmail.com' } + s.source = { :git => 'https://github.com/dhoerl/ATMHud.git', :tag => s.version.to_s } + s.requires_arc = true + s.screenshots = [ "https://github.com/dhoerl/ScreenShots/BasicFunctions.png", + "https://github.com/dhoerl/ScreenShots/AdvancedFunctions.png", + "https://github.com/dhoerl/ScreenShots/SimpleCaption.png", + "https://github.com/dhoerl/ScreenShots/Caption+Activity.png", + "https://github.com/dhoerl/ScreenShots/JustSpinner.png", + "https://github.com/dhoerl/ScreenShots/Caption+ProgressBar.png", + "https://github.com/dhoerl/ScreenShots/Caption+ProgressBar_FixedSize" ] + + s.default_subspec = 'Core' + s.subspec 'Core' do |sp| + sp.source_files = 'ATM*.{h,m}' + sp.exclude_files = 'ATMSoundFX.{h,m}' + sp.resources = '11-x.png', '19-check.png' + sp.frameworks = 'QuartzCore' + end + s.subspec 'WithSound' do |sp| + sp.source_files = 'ATM*.{h,m}' + sp.resources = '11-x.png', '19-check.png', 'pop.wav' + sp.frameworks = 'QuartzCore', 'AudioToolbox' + sp.compiler_flags = '-DATM_SOUND' + end + s.description = <<-DESC +ATMHud offers a versatile and full featured HUD for yuour iOS projects. You can use either a traditional protocol based delegate or a block based one. A Demo app shows how to use most of the feature set and both delegates. You can set any of a caption, two types of progress indicators, and an image to the HUD, which resizes as needed. You can control where the progress indicator goes (top/bot/left/right), the view grayness and cover view's grayness/opacity. If you're showing the HUD with the keyboard up (for example), you can move the HUD's center. + +Usage: + // Keep a strong ivar reference to it (ie, "ATMHud *hud") + hud = [ATMHud new]; // using the block delegate + [hud setCaption:@"Caption and an activity indicator."]; + [hud setActivity:YES]; + hud.blockDelegate = ....; // see demo project + [hud showInView:self.view]; + ... + [hud hide]; + //the block delegate can release the hud and nil the ivar (see Demo app) + +DESC +end diff --git a/ATMHud.xcodeproj/project.pbxproj b/ATMHud.xcodeproj/project.pbxproj index 82ca58d..c7a4390 100755 --- a/ATMHud.xcodeproj/project.pbxproj +++ b/ATMHud.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -31,8 +31,8 @@ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D3623240D0F684500981E51 /* ATMHudAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMHudAppDelegate.h; sourceTree = ""; }; - 1D3623250D0F684500981E51 /* ATMHudAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMHudAppDelegate.m; sourceTree = ""; }; + 1D3623240D0F684500981E51 /* ATMHudAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMHudAppDelegate.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 1D3623250D0F684500981E51 /* ATMHudAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMHudAppDelegate.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 1D6058910D05DD3D006BFB54 /* ATMHud.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ATMHud.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 1FEF4B67131CD64000C59266 /* pop.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = pop.wav; sourceTree = ""; }; @@ -40,28 +40,31 @@ 1FEF4B69131CD64000C59266 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; 1FEF4B6A131CD64000C59266 /* 11-x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "11-x.png"; sourceTree = ""; }; 1FEF4B6B131CD64000C59266 /* 19-check.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "19-check.png"; sourceTree = ""; }; - 1FEF4B71131CD64B00C59266 /* DemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoViewController.h; sourceTree = ""; }; - 1FEF4B72131CD64B00C59266 /* DemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoViewController.m; sourceTree = ""; }; - 1FEF4B74131CD65A00C59266 /* ATMHud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMHud.h; sourceTree = ""; }; - 1FEF4B75131CD65A00C59266 /* ATMHud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMHud.m; sourceTree = ""; }; - 1FEF4B76131CD65A00C59266 /* ATMHudDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMHudDelegate.h; sourceTree = ""; }; - 1FEF4B77131CD65A00C59266 /* ATMHudQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMHudQueueItem.h; sourceTree = ""; }; - 1FEF4B78131CD65A00C59266 /* ATMHudQueueItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMHudQueueItem.m; sourceTree = ""; }; - 1FEF4B79131CD65A00C59266 /* ATMHudView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMHudView.h; sourceTree = ""; }; - 1FEF4B7A131CD65A00C59266 /* ATMHudView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMHudView.m; sourceTree = ""; }; - 1FEF4B7B131CD65A00C59266 /* ATMProgressLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMProgressLayer.h; sourceTree = ""; }; - 1FEF4B7C131CD65A00C59266 /* ATMProgressLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMProgressLayer.m; sourceTree = ""; }; - 1FEF4B7D131CD65A00C59266 /* ATMSoundFX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMSoundFX.h; sourceTree = ""; }; - 1FEF4B7E131CD65A00C59266 /* ATMSoundFX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMSoundFX.m; sourceTree = ""; }; - 1FEF4B7F131CD65A00C59266 /* ATMTextLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMTextLayer.h; sourceTree = ""; }; - 1FEF4B80131CD65A00C59266 /* ATMTextLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATMTextLayer.m; sourceTree = ""; }; + 1FEF4B71131CD64B00C59266 /* DemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = DemoViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 1FEF4B72131CD64B00C59266 /* DemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = DemoViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 1FEF4B74131CD65A00C59266 /* ATMHud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMHud.h; sourceTree = ""; }; + 1FEF4B75131CD65A00C59266 /* ATMHud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMHud.m; sourceTree = ""; }; + 1FEF4B76131CD65A00C59266 /* ATMHudDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMHudDelegate.h; sourceTree = ""; }; + 1FEF4B77131CD65A00C59266 /* ATMHudQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMHudQueueItem.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 1FEF4B78131CD65A00C59266 /* ATMHudQueueItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMHudQueueItem.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 1FEF4B79131CD65A00C59266 /* ATMHudView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMHudView.h; sourceTree = ""; }; + 1FEF4B7A131CD65A00C59266 /* ATMHudView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMHudView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 1FEF4B7B131CD65A00C59266 /* ATMProgressLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMProgressLayer.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 1FEF4B7C131CD65A00C59266 /* ATMProgressLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMProgressLayer.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 1FEF4B7D131CD65A00C59266 /* ATMSoundFX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMSoundFX.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 1FEF4B7E131CD65A00C59266 /* ATMSoundFX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMSoundFX.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 1FEF4B7F131CD65A00C59266 /* ATMTextLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ATMTextLayer.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 1FEF4B80131CD65A00C59266 /* ATMTextLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ATMTextLayer.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 1FEF4B98131CD67500C59266 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 1FEF4B9A131CD67500C59266 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; - 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 32CA4F630368D1EE00C91783 /* ATMHud_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATMHud_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* ATMHud-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ATMHud-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + DE71685818B4197B00558FFF /* ATMHud.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = ATMHud.podspec; sourceTree = ""; }; + DEF0FAD1184D225800A24442 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + DEF0FAD2184D226600A24442 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -122,6 +125,9 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + DEF0FAD1184D225800A24442 /* README.md */, + DE71685818B4197B00558FFF /* ATMHud.podspec */, + DEF0FAD2184D226600A24442 /* LICENSE */, 1F1FC626131C4447002ED620 /* ATMHud */, 080E96DDFE201D6D7F000001 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, @@ -192,8 +198,11 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ATMHud" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -251,12 +260,14 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ATMHud_Prefix.pch; INFOPLIST_FILE = "ATMHud-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = ATMHud; }; name = Debug; @@ -265,10 +276,12 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ATMHud_Prefix.pch; INFOPLIST_FILE = "ATMHud-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = ATMHud; VALIDATE_PRODUCT = YES; }; @@ -277,13 +290,13 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = c99; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = ""; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.0; + ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = iphoneos; }; @@ -292,13 +305,11 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_VERSION = ""; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PREBINDING = NO; SDKROOT = iphoneos; diff --git a/ATMHud.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ATMHud.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..6135f12 --- /dev/null +++ b/ATMHud.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ATMHud.xcodeproj/project.xcworkspace/xcshareddata/ATMHud.xccheckout b/ATMHud.xcodeproj/project.xcworkspace/xcshareddata/ATMHud.xccheckout new file mode 100644 index 0000000..41c8582 --- /dev/null +++ b/ATMHud.xcodeproj/project.xcworkspace/xcshareddata/ATMHud.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 8DFDB055-31D4-49B8-AE70-9D0FA5156732 + IDESourceControlProjectName + ATMHud + IDESourceControlProjectOriginsDictionary + + 3850476F-11F3-44C5-97F7-7BF69519D6C0 + ssh://github.com/dhoerl/ATMHud.git + + IDESourceControlProjectPath + ATMHud.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 3850476F-11F3-44C5-97F7-7BF69519D6C0 + ../.. + + IDESourceControlProjectURL + ssh://github.com/dhoerl/ATMHud.git + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 3850476F-11F3-44C5-97F7-7BF69519D6C0 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 3850476F-11F3-44C5-97F7-7BF69519D6C0 + IDESourceControlWCCName + ATMHud + + + + diff --git a/ATMHud.xcodeproj/project.xcworkspace/xcuserdata/dhoerl.xcuserdatad/UserInterfaceState.xcuserstate b/ATMHud.xcodeproj/project.xcworkspace/xcuserdata/dhoerl.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..03f9724 Binary files /dev/null and b/ATMHud.xcodeproj/project.xcworkspace/xcuserdata/dhoerl.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ATMHud.xcodeproj/project.xcworkspace/xcuserdata/dhoerl.xcuserdatad/WorkspaceSettings.xcsettings b/ATMHud.xcodeproj/project.xcworkspace/xcuserdata/dhoerl.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..06c7d50 --- /dev/null +++ b/ATMHud.xcodeproj/project.xcworkspace/xcuserdata/dhoerl.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges + + + diff --git a/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..59ec345 --- /dev/null +++ b/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcschemes/ATMHud.xcscheme b/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcschemes/ATMHud.xcscheme new file mode 100644 index 0000000..8e54c3c --- /dev/null +++ b/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcschemes/ATMHud.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcschemes/xcschememanagement.plist b/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..614661d --- /dev/null +++ b/ATMHud.xcodeproj/xcuserdata/dhoerl.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + ATMHud.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 1D6058900D05DD3D006BFB54 + + primary + + + + + diff --git a/ATMHudDelegate.h b/ATMHudDelegate.h index 2d86aad..6001b0e 100644 --- a/ATMHudDelegate.h +++ b/ATMHudDelegate.h @@ -4,22 +4,27 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ @class ATMHud; -@protocol ATMHudDelegate +@protocol ATMHudDelegate @optional -- (void)userDidTapHud:(ATMHud *)_hud; -- (void)hudWillAppear:(ATMHud *)_hud; -- (void)hudDidAppear:(ATMHud *)_hud; -- (void)hudWillUpdate:(ATMHud *)_hud; -- (void)hudDidUpdate:(ATMHud *)_hud; -- (void)hudWillDisappear:(ATMHud *)_hud; -- (void)hudDidDisappear:(ATMHud *)_hud; +- (void)userDidTapHud:(ATMHud *)theHud; // tapped the visible HUD +- (void)userDidTapOutsideHud:(ATMHud *)theHud; // tapped outside the HUD + +- (void)hudWillAppear:(ATMHud *)theHud; +- (void)hudDidAppear:(ATMHud *)theHud; +- (void)hudWillUpdate:(ATMHud *)theHud; +- (void)hudDidUpdate:(ATMHud *)theHud; +- (void)hudWillDisappear:(ATMHud *)theHud; + +@required +- (void)hudDidDisappear:(ATMHud *)theHud; @end diff --git a/ATMHudQueueItem.h b/ATMHudQueueItem.h index 2311d0a..d9741dc 100644 --- a/ATMHudQueueItem.h +++ b/ATMHudQueueItem.h @@ -4,24 +4,17 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ -#import #import "ATMHud.h" -@interface ATMHudQueueItem : NSObject { - NSString *caption; - UIImage *image; - BOOL showActivity; - ATMHudAccessoryPosition accessoryPosition; - UIActivityIndicatorViewStyle activityStyle; -} - -@property (nonatomic, retain) NSString *caption; -@property (nonatomic, retain) UIImage *image; +@interface ATMHudQueueItem : NSObject +@property (nonatomic, strong) NSString *caption; +@property (nonatomic, strong) UIImage *image; @property (nonatomic, assign) BOOL showActivity; @property (nonatomic, assign) ATMHudAccessoryPosition accessoryPosition; @property (nonatomic, assign) UIActivityIndicatorViewStyle activityStyle; diff --git a/ATMHudQueueItem.m b/ATMHudQueueItem.m index 6eef7dd..c2d3447 100644 --- a/ATMHudQueueItem.m +++ b/ATMHudQueueItem.m @@ -4,31 +4,25 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import "ATMHudQueueItem.h" @implementation ATMHudQueueItem -@synthesize caption, image, showActivity, accessoryPosition, activityStyle; -- (id)init { +- (instancetype)init +{ if ((self = [super init])) { - caption = @""; - image = nil; - showActivity = NO; - accessoryPosition = ATMHudAccessoryPositionBottom; - activityStyle = UIActivityIndicatorViewStyleWhite; + _caption = @""; + _accessoryPosition = ATMHudAccessoryPositionBottom; + _activityStyle = UIActivityIndicatorViewStyleWhite; } return self; } -- (void)dealloc { - [caption release]; - [image release]; - [super dealloc]; -} @end diff --git a/ATMHudView.h b/ATMHudView.h index 6c53f7b..307c06b 100644 --- a/ATMHudView.h +++ b/ATMHudView.h @@ -4,11 +4,14 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ +#import + @class ATMTextLayer, ATMProgressLayer, ATMHud, ATMHudQueueItem; typedef enum { @@ -17,68 +20,28 @@ typedef enum { ATMHudApplyModeHide } ATMHudApplyMode; -@interface ATMHudView : UIView { - NSString *caption; - UIImage *image; - UIActivityIndicatorView *activity; - UIActivityIndicatorViewStyle activityStyle; - ATMHud *p; - - BOOL showActivity; - - CGFloat progress; - - CGRect targetBounds; - CGRect captionRect; - CGRect progressRect; - CGRect activityRect; - CGRect imageRect; - - CGSize fixedSize; - CGSize activitySize; - - CALayer *backgroundLayer; - CALayer *imageLayer; - ATMTextLayer *captionLayer; - ATMProgressLayer *progressLayer; -} -@property (nonatomic, retain) NSString *caption; -@property (nonatomic, retain) UIImage *image; -@property (nonatomic, retain) UIActivityIndicatorView *activity; +@interface ATMHudView : UIView +@property (nonatomic, weak) ATMHud *hud; // delegate +@property (nonatomic, strong) NSString *caption; +@property (nonatomic, strong) UIImage *image; +@property (nonatomic, strong) UIActivityIndicatorView *activity; @property (nonatomic, assign) UIActivityIndicatorViewStyle activityStyle; -@property (nonatomic, retain) ATMHud *p; @property (nonatomic, assign) BOOL showActivity; - @property (nonatomic, assign) CGFloat progress; - -@property (nonatomic, assign) CGRect targetBounds; -@property (nonatomic, assign) CGRect captionRect; -@property (nonatomic, assign) CGRect progressRect; -@property (nonatomic, assign) CGRect activityRect; -@property (nonatomic, assign) CGRect imageRect; - @property (nonatomic, assign) CGSize fixedSize; @property (nonatomic, assign) CGSize activitySize; +@property (nonatomic, strong) CALayer *backgroundLayer; +@property (nonatomic, strong) UIColor *hudBackgroundColor; -@property (nonatomic, retain) CALayer *backgroundLayer; -@property (nonatomic, retain) CALayer *imageLayer; -@property (nonatomic, retain) ATMTextLayer *captionLayer; -@property (nonatomic, retain) ATMProgressLayer *progressLayer; +- (instancetype)initWithFrame:(CGRect)frame andController:(ATMHud *)c; -- (id)initWithFrame:(CGRect)frame andController:(ATMHud *)c; - -- (CGRect)sharpRect:(CGRect)rect; -- (CGPoint)sharpPoint:(CGPoint)point; - -- (void)calculate; - (CGSize)calculateSizeForQueueItem:(ATMHudQueueItem *)item; -- (CGSize)sizeForActivityStyle:(UIActivityIndicatorViewStyle)style; -- (void)applyWithMode:(ATMHudApplyMode)mode; - (void)show; - (void)reset; - (void)update; - (void)hide; @end + diff --git a/ATMHudView.m b/ATMHudView.m index dc8d679..09b39fb 100644 --- a/ATMHudView.m +++ b/ATMHudView.m @@ -4,290 +4,362 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ + +#import #import "ATMHudView.h" #import "ATMTextLayer.h" #import "ATMProgressLayer.h" #import "ATMHud.h" -#import #import "ATMHudDelegate.h" #import "ATMHudQueueItem.h" +//@interface ATMHudView () +//@end + +#define SHADOW_OPACITY 0.4f +#define CORNER_RADIUS 10 + @implementation ATMHudView -@synthesize caption, image, activity, activityStyle, p; -@synthesize showActivity; -@synthesize progress; -@synthesize targetBounds, captionRect, progressRect, activityRect, imageRect; -@synthesize fixedSize, activitySize; -@synthesize backgroundLayer, imageLayer, captionLayer, progressLayer; - -- (CGRect)sharpRect:(CGRect)rect { - CGRect r = rect; - r.origin.x = (int)r.origin.x; - r.origin.y = (int)r.origin.y; - return r; +{ + CGRect targetBounds; + CALayer *imageLayer; + ATMTextLayer *captionLayer; + ATMProgressLayer *progressLayer; + CGRect captionRect; + CGRect activityRect; + CGRect progressRect; + CGRect imageRect; + BOOL didHide; + UIFont *bsf14; } -- (CGPoint)sharpPoint:(CGPoint)point { +- (CGPoint)integralPoint:(CGPoint)point +{ CGPoint _p = point; - _p.x = (int)_p.x; - _p.y = (int)_p.y; + _p.x = rintf((float)_p.x); + _p.y = rintf((float)_p.y); return _p; } -- (id)initWithFrame:(CGRect)frame andController:(ATMHud *)c { +- (void)removeFromSuperview +{ + //NSLog(@"removeFromSuperview"); + [super removeFromSuperview]; +} + +- (instancetype)initWithFrame:(CGRect)frame andController:(ATMHud *)h +{ if ((self = [super initWithFrame:frame])) { - self.p = c; + _hud = h; self.backgroundColor = [UIColor clearColor]; self.opaque = NO; self.alpha = 0.0; - backgroundLayer = [[CALayer alloc] init]; - backgroundLayer.cornerRadius = 10; - backgroundLayer.backgroundColor = [UIColor colorWithWhite:0.0 alpha:p.alpha].CGColor; - [self.layer addSublayer:backgroundLayer]; + bsf14 = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; + + _backgroundLayer = [CALayer new]; + _backgroundLayer.cornerRadius = CORNER_RADIUS; + _backgroundLayer.backgroundColor = _hudBackgroundColor.CGColor; + [self.layer addSublayer:_backgroundLayer]; - captionLayer = [[ATMTextLayer alloc] init]; + captionLayer = [ATMTextLayer new]; captionLayer.contentsScale = [[UIScreen mainScreen] scale]; captionLayer.anchorPoint = CGPointMake(0, 0); [self.layer addSublayer:captionLayer]; - imageLayer = [[CALayer alloc] init]; + imageLayer = [CALayer new]; imageLayer.anchorPoint = CGPointMake(0, 0); + [self.layer addSublayer:imageLayer]; - progressLayer = [[ATMProgressLayer alloc] init]; + progressLayer = [ATMProgressLayer new]; progressLayer.contentsScale = [[UIScreen mainScreen] scale]; progressLayer.anchorPoint = CGPointMake(0, 0); [self.layer addSublayer:progressLayer]; + + _activityStyle = UIActivityIndicatorViewStyleWhiteLarge; + _activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: _activityStyle]; // UIActivityIndicatorView + _activity.hidesWhenStopped = YES; + [self addSubview:_activity]; + + // Remove shadow - its just an old school effect + // self.layer.shadowColor = [UIColor blackColor].CGColor; + // self.layer.shadowRadius = 5.0; // DFH: was 8 + // self.layer.shadowOffset = CGSizeMake(0.0, 0.0); // DFH: was 3 + // self.layer.shadowOpacity = 0.05f; // DFH: was 0.3 + + _activitySize = CGSizeMake(20, 20); - activity = [[UIActivityIndicatorView alloc] init]; - activity.hidesWhenStopped = YES; - [self addSubview:activity]; - - self.layer.shadowColor = [UIColor blackColor].CGColor; - self.layer.shadowRadius = 8.0; - self.layer.shadowOffset = CGSizeMake(0.0, 3.0); - self.layer.shadowOpacity = 0.4; - - progressRect = CGRectMake(0, 0, 210, 20); - activityStyle = UIActivityIndicatorViewStyleWhite; - activitySize = CGSizeMake(20, 20); + didHide = YES; + + if(_hud.usesParallax) { + // Set vertical effect + UIInterpolatingMotionEffect *verticalMotionEffect = + [[UIInterpolatingMotionEffect alloc] + initWithKeyPath:@"center.y" + type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; + verticalMotionEffect.minimumRelativeValue = @(-10); + verticalMotionEffect.maximumRelativeValue = @(10); + + // Set horizontal effect + UIInterpolatingMotionEffect *horizontalMotionEffect = + [[UIInterpolatingMotionEffect alloc] + initWithKeyPath:@"center.x" + type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; + horizontalMotionEffect.minimumRelativeValue = @(-10); + horizontalMotionEffect.maximumRelativeValue = @(10); + + // Create group to combine both + UIMotionEffectGroup *group = [UIMotionEffectGroup new]; + group.motionEffects = @[horizontalMotionEffect, verticalMotionEffect]; + + // Add both effects to your view + [self addMotionEffect:group]; + } + } return self; } -- (void)dealloc { - [caption release]; - [image release]; - [activity release]; - [p release]; +- (void)dealloc +{ + //NSLog(@"ATM_HUD_VIEW DEALLOC"); +} + +- (void)setProgress:(CGFloat)_p +{ + _p = MIN(MAX(0,_p),1); - [backgroundLayer release]; - [imageLayer release]; - [captionLayer release]; - [progressLayer release]; + if (_p > 0 && _p < 0.08f) _p = 0.08f; + if (_p == _progress) return; - [super dealloc]; + _progress = _p; + progressLayer.theProgress = _progress; } -- (void)setProgress:(CGFloat)_p { - _p = MIN(MAX(0,_p),1); +- (void)setHudBackgroundColor:(UIColor *)color { + _hudBackgroundColor = color; + _backgroundLayer.backgroundColor = color.CGColor; +} + +- (CGRect)calcString:(NSString *)str sizeForSize:(CGSize)origSize +{ + NSStringDrawingContext *sdc = [NSStringDrawingContext new]; + sdc.minimumScaleFactor = 0; + + NSParagraphStyle *paragraphStyle = [NSMutableParagraphStyle defaultParagraphStyle]; // uses LineBreakWordWrapping + NSDictionary *dict = @{ NSFontAttributeName : bsf14, NSParagraphStyleAttributeName : paragraphStyle }; + + CGRect r = [_caption boundingRectWithSize:origSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:sdc]; - if (_p > 0 && _p < 0.08) _p = 0.08; - if(_p == progress) return; - progress = _p; + return CGRectIntegral(r); } -- (void)calculate { - if (!caption || [caption isEqualToString:@""]) { - activityRect = CGRectMake(p.margin, p.margin, activitySize.width, activitySize.height); - targetBounds = CGRectMake(0, 0, p.margin*2+activitySize.width, p.margin*2+activitySize.height); +- (void)calculate +{ + progressLayer.progressStyle = _hud.progressStyle; + progressRect.size = progressLayer.progressSize; + + if (![_caption length]) { + activityRect = CGRectMake(_hud.margin, _hud.margin, _activitySize.width, _activitySize.height); + targetBounds = CGRectMake(0, 0, _hud.margin*2+_activitySize.width, _hud.margin*2+_activitySize.height); } else { BOOL hasFixedSize = NO; - CGSize captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap]; - - if (fixedSize.width > 0 & fixedSize.height > 0) { - CGSize s = fixedSize; - if (progress > 0 && (fixedSize.width < progressRect.size.width+p.margin*2)) { - s.width = progressRect.size.width+p.margin*2; + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(160, 200)]; + if (_fixedSize.width > 0 & _fixedSize.height > 0) { + CGSize s = _fixedSize; + if (_progress > 0 && (_fixedSize.width < progressRect.size.width+_hud.margin*2)) { + s.width = progressRect.size.width+_hud.margin*2; } hasFixedSize = YES; - captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(s.width-p.margin*2, 200) lineBreakMode:UILineBreakModeWordWrap]; + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(s.width-_hud.margin*2, 200)]; targetBounds = CGRectMake(0, 0, s.width, s.height); } - - captionRect = CGRectZero; - captionRect.size = captionSize; + float adjustment = 0; - CGFloat marginX = p.margin; - CGFloat marginY = p.margin; + CGFloat marginX = _hud.margin; + CGFloat marginY = _hud.margin; if (!hasFixedSize) { - if (p.accessoryPosition == ATMHudAccessoryPositionTop || p.accessoryPosition == ATMHudAccessoryPositionBottom) { - if (progress > 0) { - adjustment = p.padding+progressRect.size.height; - if (captionSize.width+p.margin*2 < progressRect.size.width) { - captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(progressRect.size.width, 200) lineBreakMode:UILineBreakModeWordWrap]; - captionRect.size = captionSize; - targetBounds = CGRectMake(0, 0, progressRect.size.width+p.margin*2, captionSize.height+p.margin*2+adjustment); + if (_hud.accessoryPosition == ATMHudAccessoryPositionTop || _hud.accessoryPosition == ATMHudAccessoryPositionBottom) { + if (_progress > 0) { + adjustment = _hud.padding+progressRect.size.height; + if (captionRect.size.width+_hud.margin*2 < progressRect.size.width) { + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(progressRect.size.width, 200)]; + targetBounds = CGRectMake(0, 0, progressRect.size.width+_hud.margin*2, captionRect.size.height+_hud.margin*2+adjustment); } else { - targetBounds = CGRectMake(0, 0, captionSize.width+p.margin*2, captionSize.height+p.margin*2+adjustment); + targetBounds = CGRectMake(0, 0, captionRect.size.width+_hud.margin*2, captionRect.size.height+_hud.margin*2+adjustment); } } else { - if (image) { - adjustment = p.padding+image.size.height; - } else if (showActivity) { - adjustment = p.padding+activitySize.height; + if (_image) { + adjustment = _hud.padding+_image.size.height; + } else if (_showActivity) { + adjustment = _hud.padding+_activitySize.height; } - targetBounds = CGRectMake(0, 0, captionSize.width+p.margin*2, captionSize.height+p.margin*2+adjustment); + targetBounds = CGRectMake(0, 0, captionRect.size.width+_hud.margin*2, captionRect.size.height+_hud.margin*2+adjustment); } - } else if (p.accessoryPosition == ATMHudAccessoryPositionLeft || p.accessoryPosition == ATMHudAccessoryPositionRight) { - if (image) { - adjustment = p.padding+image.size.width; - } else if (showActivity) { - adjustment = p.padding+activitySize.height; + } else if (_hud.accessoryPosition == ATMHudAccessoryPositionLeft || _hud.accessoryPosition == ATMHudAccessoryPositionRight) { + if (_image) { + adjustment = _hud.padding+_image.size.width; + } else if (_showActivity) { + adjustment = _hud.padding+_activitySize.height; } - targetBounds = CGRectMake(0, 0, captionSize.width+p.margin*2+adjustment, captionSize.height+p.margin*2); + targetBounds = CGRectMake(0, 0, captionRect.size.width+_hud.margin*2+adjustment, captionRect.size.height+_hud.margin*2); } } else { - if (p.accessoryPosition == ATMHudAccessoryPositionTop || p.accessoryPosition == ATMHudAccessoryPositionBottom) { - if (progress > 0) { - adjustment = p.padding+progressRect.size.height; - if (captionSize.width+p.margin*2 < progressRect.size.width) { - captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(progressRect.size.width, 200) lineBreakMode:UILineBreakModeWordWrap]; - captionRect.size = captionSize; + if (_hud.accessoryPosition == ATMHudAccessoryPositionTop || _hud.accessoryPosition == ATMHudAccessoryPositionBottom) { + if (_progress > 0) { + adjustment = _hud.padding+progressRect.size.height; + if (captionRect.size.width+_hud.margin*2 < progressRect.size.width) { + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(progressRect.size.width, 200)]; } } else { - if (image) { - adjustment = p.padding+image.size.height; - } else if (showActivity) { - adjustment = p.padding+activitySize.height; + if (_image) { + adjustment = _hud.padding+_image.size.height; + } else if (_showActivity) { + adjustment = _hud.padding+_activitySize.height; } } - int deltaWidth = targetBounds.size.width-captionSize.width; - marginX = 0.5*deltaWidth; - if (marginX < p.margin) { - captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap]; - captionRect.size = captionSize; - - targetBounds = CGRectMake(0, 0, captionSize.width+2*p.margin, targetBounds.size.height); - marginX = p.margin; + long deltaWidth = lrintf(targetBounds.size.width - captionRect.size.width); + marginX = 0.5f*deltaWidth; + if (marginX < _hud.margin) { + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(160, 200)]; + targetBounds = CGRectMake(0, 0, captionRect.size.width+2*_hud.margin, targetBounds.size.height); + marginX = _hud.margin; } - int deltaHeight = targetBounds.size.height-(adjustment+captionSize.height); - marginY = 0.5*deltaHeight; - if (marginY < p.margin) { - targetBounds = CGRectMake(0, 0, targetBounds.size.width, captionSize.height+2*p.margin+adjustment); - marginY = p.margin; + long deltaHeight = lrintf(targetBounds.size.height - (adjustment+captionRect.size.height)); + marginY = 0.5f*deltaHeight; + if (marginY < _hud.margin) { + targetBounds = CGRectMake(0, 0, targetBounds.size.width, captionRect.size.height+2*_hud.margin+adjustment); + marginY = _hud.margin; } - } else if (p.accessoryPosition == ATMHudAccessoryPositionLeft || p.accessoryPosition == ATMHudAccessoryPositionRight) { - if (image) { - adjustment = p.padding+image.size.width; - } else if (showActivity) { - adjustment = p.padding+activitySize.width; + } else if (_hud.accessoryPosition == ATMHudAccessoryPositionLeft || _hud.accessoryPosition == ATMHudAccessoryPositionRight) { + if (_image) { + adjustment = _hud.padding+_image.size.width; + } else if (_showActivity) { + adjustment = _hud.padding+_activitySize.width; } - int deltaWidth = targetBounds.size.width-(adjustment+captionSize.width); - marginX = 0.5*deltaWidth; - if (marginX < p.margin) { - captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap]; - captionRect.size = captionSize; - - targetBounds = CGRectMake(0, 0, adjustment+captionSize.width+2*p.margin, targetBounds.size.height); - marginX = p.margin; + long deltaWidth = lrintf(targetBounds.size.width-(adjustment+captionRect.size.width)); + marginX = 0.5f*deltaWidth; + if (marginX < _hud.margin) { + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(160, 200)]; + targetBounds = CGRectMake(0, 0, adjustment+captionRect.size.width+2*_hud.margin, targetBounds.size.height); + marginX = _hud.margin; } - int deltaHeight = targetBounds.size.height-captionSize.height; - marginY = 0.5*deltaHeight; - if (marginY < p.margin) { - targetBounds = CGRectMake(0, 0, targetBounds.size.width, captionSize.height+2*p.margin); - marginY = p.margin; + long deltaHeight = lrintf(targetBounds.size.height-captionRect.size.height); + marginY = 0.5f*deltaHeight; + if (marginY < _hud.margin) { + targetBounds = CGRectMake(0, 0, targetBounds.size.width, captionRect.size.height+2*_hud.margin); + marginY = _hud.margin; } } } - switch (p.accessoryPosition) { - case ATMHudAccessoryPositionTop: { - activityRect = CGRectMake((targetBounds.size.width-activitySize.width)*0.5, marginY, activitySize.width, activitySize.height); - - imageRect = CGRectZero; - imageRect.origin.x = (targetBounds.size.width-image.size.width)*0.5; - imageRect.origin.y = marginY; - imageRect.size = image.size; - - progressRect = CGRectMake((targetBounds.size.width-progressRect.size.width)*0.5, marginY, progressRect.size.width, progressRect.size.height); - - captionRect.origin.x = (targetBounds.size.width-captionSize.width)*0.5; - captionRect.origin.y = adjustment+marginY; - break; - } - - case ATMHudAccessoryPositionRight: { - activityRect = CGRectMake(marginX+p.padding+captionSize.width, (targetBounds.size.height-activitySize.height)*0.5, activitySize.width, activitySize.height); - - imageRect = CGRectZero; - imageRect.origin.x = marginX+p.padding+captionSize.width; - imageRect.origin.y = (targetBounds.size.height-image.size.height)*0.5; - imageRect.size = image.size; - - captionRect.origin.x = marginX; - captionRect.origin.y = marginY; - break; - } - - case ATMHudAccessoryPositionBottom: { - activityRect = CGRectMake((targetBounds.size.width-activitySize.width)*0.5, captionRect.size.height+marginY+p.padding, activitySize.width, activitySize.height); - - imageRect = CGRectZero; - imageRect.origin.x = (targetBounds.size.width-image.size.width)*0.5; - imageRect.origin.y = captionRect.size.height+marginY+p.padding; - imageRect.size = image.size; - - progressRect = CGRectMake((targetBounds.size.width-progressRect.size.width)*0.5, captionRect.size.height+marginY+p.padding, progressRect.size.width, progressRect.size.height); - - captionRect.origin.x = (targetBounds.size.width-captionSize.width)*0.5; - captionRect.origin.y = marginY; - break; + switch (_hud.accessoryPosition) { + case ATMHudAccessoryPositionTop: { + activityRect = CGRectMake((targetBounds.size.width-_activitySize.width)*0.5f, marginY, _activitySize.width, _activitySize.height); + + imageRect = CGRectZero; + if (_image) + imageRect.origin.x = (targetBounds.size.width-_image.size.width)*0.5f; + else + imageRect.origin.x = (targetBounds.size.width)*0.5f; + + imageRect.origin.y = marginY; + if (_image && _image.size.width > 0.0f && _image.size.height > 0.0f) { + imageRect.size = _image.size; + } + //progressRect = CGRectMake((targetBounds.size.width-progressRect.size.width)*0.5f, marginY, progressRect.size.width, progressRect.size.height); + progressRect.origin = CGPointMake((targetBounds.size.width-progressRect.size.width)*0.5f, marginY); + captionRect.origin.x = (targetBounds.size.width-captionRect.size.width)*0.5f; + captionRect.origin.y = adjustment+marginY; + break; + } + + case ATMHudAccessoryPositionRight: { + activityRect = CGRectMake(marginX+_hud.padding+captionRect.size.width, (targetBounds.size.height-_activitySize.height)*0.5f, _activitySize.width, _activitySize.height); + + imageRect = CGRectZero; + imageRect.origin.x = marginX+_hud.padding+captionRect.size.width; + if (_image) { + imageRect.origin.y = (targetBounds.size.height-_image.size.height)*0.5f; + imageRect.size = _image.size; } - - case ATMHudAccessoryPositionLeft: { - activityRect = CGRectMake(marginX, (targetBounds.size.height-activitySize.height)*0.5, activitySize.width, activitySize.height); - - imageRect = CGRectZero; - imageRect.origin.x = marginX; - imageRect.origin.y = (targetBounds.size.height-image.size.height)*0.5; - imageRect.size = image.size; - - captionRect.origin.x = marginX+adjustment; - captionRect.origin.y = marginY; - break; + + captionRect.origin.x = marginX; + captionRect.origin.y = marginY; + break; + } + + case ATMHudAccessoryPositionBottom: { + activityRect = CGRectMake((targetBounds.size.width-_activitySize.width)*0.5f, captionRect.size.height+marginY+_hud.padding, _activitySize.width, _activitySize.height); + + imageRect = CGRectZero; + if (_image) + imageRect.origin.x = (targetBounds.size.width-_image.size.width)*0.5f; + else + imageRect.origin.x = (targetBounds.size.width)*0.5f; + imageRect.origin.y = captionRect.size.height+marginY+_hud.padding; + if (_image) + imageRect.size = _image.size; + + //progressRect = CGRectMake((targetBounds.size.width-progressRect.size.width)*0.5f, captionRect.size.height+marginY+_hud.padding, progressRect.size.width, progressRect.size.height); + progressRect.origin = CGPointMake((targetBounds.size.width-progressRect.size.width)*0.5f, captionRect.size.height+marginY+_hud.padding); + captionRect.origin.x = (targetBounds.size.width-captionRect.size.width)*0.5f; + captionRect.origin.y = marginY; + break; + } + + case ATMHudAccessoryPositionLeft: { + activityRect = CGRectMake(marginX, (targetBounds.size.height-_activitySize.height)*0.5f, _activitySize.width, _activitySize.height); + + imageRect = CGRectZero; + imageRect.origin.x = marginX; + if (_image) { + imageRect.origin.y = (targetBounds.size.height-_image.size.height)*0.5f; + imageRect.size = _image.size; + } else { + imageRect.origin.y = (targetBounds.size.height)*0.5f; } + + captionRect.origin.x = marginX+adjustment; + captionRect.origin.y = marginY; + break; + } } } } -- (CGSize)sizeForActivityStyle:(UIActivityIndicatorViewStyle)style { +- (CGSize)sizeForActivityStyle:(UIActivityIndicatorViewStyle)style +{ + CGSize size; if (style == UIActivityIndicatorViewStyleWhiteLarge) { - return CGSizeMake(37, 37); + size = CGSizeMake(37, 37); } else { - return CGSizeMake(20, 20); + size = CGSizeMake(20, 20); } + return size; } -- (CGSize)calculateSizeForQueueItem:(ATMHudQueueItem *)item { +- (CGSize)calculateSizeForQueueItem:(ATMHudQueueItem *)item +{ CGSize targetSize = CGSizeZero; CGSize styleSize = [self sizeForActivityStyle:item.activityStyle]; if (!item.caption || [item.caption isEqualToString:@""]) { - targetSize = CGSizeMake(p.margin*2+styleSize.width, p.margin*2+styleSize.height); + targetSize = CGSizeMake(_hud.margin*2+styleSize.width, _hud.margin*2+styleSize.height); } else { BOOL hasFixedSize = NO; - CGSize captionSize = [item.caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap]; + captionRect = [self calcString:item.caption sizeForSize:CGSizeMake(160, 200)]; float adjustment = 0; CGFloat marginX = 0; @@ -295,59 +367,57 @@ - (CGSize)calculateSizeForQueueItem:(ATMHudQueueItem *)item { if (!hasFixedSize) { if (item.accessoryPosition == ATMHudAccessoryPositionTop || item.accessoryPosition == ATMHudAccessoryPositionBottom) { if (item.image) { - adjustment = p.padding+item.image.size.height; + adjustment = _hud.padding+item.image.size.height; } else if (item.showActivity) { - adjustment = p.padding+styleSize.height; + adjustment = _hud.padding+styleSize.height; } - targetSize = CGSizeMake(captionSize.width+p.margin*2, captionSize.height+p.margin*2+adjustment); + targetSize = CGSizeMake(captionRect.size.width+_hud.margin*2, captionRect.size.height+_hud.margin*2+adjustment); } else if (item.accessoryPosition == ATMHudAccessoryPositionLeft || item.accessoryPosition == ATMHudAccessoryPositionRight) { if (item.image) { - adjustment = p.padding+item.image.size.width; + adjustment = _hud.padding+item.image.size.width; } else if (item.showActivity) { - adjustment = p.padding+styleSize.width; + adjustment = _hud.padding+styleSize.width; } - targetSize = CGSizeMake(captionSize.width+p.margin*2+adjustment, captionSize.height+p.margin*2); + targetSize = CGSizeMake(captionRect.size.width+_hud.margin*2+adjustment, captionRect.size.height+_hud.margin*2); } } else { if (item.accessoryPosition == ATMHudAccessoryPositionTop || item.accessoryPosition == ATMHudAccessoryPositionBottom) { if (item.image) { - adjustment = p.padding+item.image.size.height; + adjustment = _hud.padding+item.image.size.height; } else if (item.showActivity) { - adjustment = p.padding+styleSize.height; + adjustment = _hud.padding+styleSize.height; } - int deltaWidth = targetSize.width-captionSize.width; - marginX = 0.5*deltaWidth; - if (marginX < p.margin) { - captionSize = [item.caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap]; - - targetSize = CGSizeMake(captionSize.width+2*p.margin, targetSize.height); + long deltaWidth = lrintf(targetSize.width-captionRect.size.width); + marginX = 0.5f*deltaWidth; + if (marginX < _hud.margin) { + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(160, 200)]; + targetSize = CGSizeMake(captionRect.size.width+2*_hud.margin, targetSize.height); } - int deltaHeight = targetSize.height-(adjustment+captionSize.height); - marginY = 0.5*deltaHeight; - if (marginY < p.margin) { - targetSize = CGSizeMake(targetSize.width, captionSize.height+2*p.margin+adjustment); + long deltaHeight = lrintf(targetSize.height-(adjustment+captionRect.size.height)); + marginY = 0.5f*deltaHeight; + if (marginY < _hud.margin) { + targetSize = CGSizeMake(targetSize.width, captionRect.size.height+2*_hud.margin+adjustment); } } else if (item.accessoryPosition == ATMHudAccessoryPositionLeft || item.accessoryPosition == ATMHudAccessoryPositionRight) { if (item.image) { - adjustment = p.padding+item.image.size.width; + adjustment = _hud.padding+item.image.size.width; } else if (item.showActivity) { - adjustment = p.padding+styleSize.width; + adjustment = _hud.padding+styleSize.width; } - int deltaWidth = targetSize.width-(adjustment+captionSize.width); - marginX = 0.5*deltaWidth; - if (marginX < p.margin) { - captionSize = [item.caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap]; - - targetSize = CGSizeMake(adjustment+captionSize.width+2*p.margin, targetSize.height); + long deltaWidth = lrintf(targetSize.width-(adjustment+captionRect.size.width)); + marginX = 0.5f*deltaWidth; + if (marginX < _hud.margin) { + captionRect = [self calcString:_caption sizeForSize:CGSizeMake(160, 200)]; + targetSize = CGSizeMake(adjustment+captionRect.size.width+2*_hud.margin, targetSize.height); } - int deltaHeight = targetSize.height-captionSize.height; - marginY = 0.5*deltaHeight; - if (marginY < p.margin) { - targetSize = CGSizeMake(targetSize.width, captionSize.height+2*p.margin); + long deltaHeight = lrintf(targetSize.height-captionRect.size.height); + marginY = 0.5f*deltaHeight; + if (marginY < _hud.margin) { + targetSize = CGSizeMake(targetSize.width, captionRect.size.height+2*_hud.margin); } } } @@ -355,204 +425,267 @@ - (CGSize)calculateSizeForQueueItem:(ATMHudQueueItem *)item { return targetSize; } -- (void)applyWithMode:(ATMHudApplyMode)mode { +- (void)applyWithMode:(ATMHudApplyMode)mode +{ + id delegate = (id)_hud.delegate; + ATMblockDelegate blockDelegate = _hud.blockDelegate; + switch (mode) { - case ATMHudApplyModeShow: { - if (CGPointEqualToPoint(p.center, CGPointZero)) { - self.frame = CGRectMake((self.superview.bounds.size.width-targetBounds.size.width)*0.5, (self.superview.bounds.size.height-targetBounds.size.height)*0.5, targetBounds.size.width, targetBounds.size.height); - } else { - self.bounds = CGRectMake(0, 0, targetBounds.size.width, targetBounds.size.height); - self.center = p.center; + case ATMHudApplyModeShow: { + // NSLog(@"ATMHud: ATMHudApplyModeShow delegate=%@", delegate); + if (CGPointEqualToPoint(_hud.center, CGPointZero)) { + self.frame = CGRectMake((self.superview.bounds.size.width-targetBounds.size.width)*0.5f, (self.superview.bounds.size.height-targetBounds.size.height)*0.5f, targetBounds.size.width, targetBounds.size.height); + } else { + self.bounds = CGRectMake(0, 0, targetBounds.size.width, targetBounds.size.height); + self.center = _hud.center; + } + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [CATransaction setCompletionBlock:^{ + if (_showActivity) { + _activity.activityIndicatorViewStyle = _activityStyle; + _activity.frame = CGRectIntegral(activityRect); } - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - [CATransaction setCompletionBlock:^{ - if (showActivity) { - activity.activityIndicatorViewStyle = activityStyle; - activity.frame = [self sharpRect:activityRect]; - } - - CGRect r = self.frame; - [self setFrame:[self sharpRect:r]]; - - if ([(id)p.delegate respondsToSelector:@selector(hudWillAppear:)]) { - [p.delegate hudWillAppear:p]; - } - - self.transform = CGAffineTransformMakeScale(p.appearScaleFactor, p.appearScaleFactor); - - [UIView animateWithDuration:.1 - animations:^{ - self.transform = CGAffineTransformMakeScale(1.0, 1.0); - self.alpha = 1.0; - } - completion:^(BOOL finished){ - if (finished) { - if (!p.allowSuperviewInteraction) { - self.superview.userInteractionEnabled = YES; - } - if (![p.showSound isEqualToString:@""] && p.showSound != NULL) { - [p playSound:p.showSound]; - } - if ([(id)p.delegate respondsToSelector:@selector(hudDidAppear:)]) { - [p.delegate hudDidAppear:p]; - } - } - }]; - }]; + CGRect r = self.frame; + self.frame = CGRectIntegral(r); + if ([delegate respondsToSelector:@selector(hudWillAppear:)]) { + [delegate hudWillAppear:_hud]; + } + if (blockDelegate) { + blockDelegate(ATMHudActionWillAppear, _hud); + } + + self.transform = CGAffineTransformMakeScale(_hud.appearScaleFactor, _hud.appearScaleFactor); + + [UIView animateWithDuration:_hud.animateDuration + animations:^{ + self.transform = CGAffineTransformMakeScale(1.0, 1.0); + self.alpha = 1.0; + } + completion:^(BOOL finished){ + // if (finished) Got to do this regardless of whether it finished or not. + { + if (!_hud.allowSuperviewInteraction) { + self.superview.userInteractionEnabled = YES; + } +#ifdef ATM_SOUND + if (![_hud.showSound isEqualToString:@""] && _hud.showSound != NULL) { + [_hud playSound:_hud.showSound]; + } +#endif + if ([delegate respondsToSelector:@selector(hudDidAppear:)]) { + [delegate hudDidAppear:_hud]; + } + if (blockDelegate) { + blockDelegate(ATMHudActionDidAppear, _hud); + } + } + }]; + }]; + + _backgroundLayer.position = CGPointMake(0.5f*targetBounds.size.width, 0.5f*targetBounds.size.height); + _backgroundLayer.bounds = targetBounds; + + captionLayer.position = [self integralPoint:CGPointMake(captionRect.origin.x, captionRect.origin.y)]; + captionLayer.bounds = CGRectMake(0, 0, captionRect.size.width, captionRect.size.height); + CABasicAnimation *cAnimation = [CABasicAnimation animationWithKeyPath:@"caption"]; + cAnimation.duration = 0.001; + cAnimation.toValue = _caption; + [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"]; + captionLayer.caption = _caption; + imageLayer.contents = (id)_image.CGImage; + imageLayer.position = [self integralPoint:CGPointMake(imageRect.origin.x, imageRect.origin.y)]; + imageLayer.bounds = CGRectMake(0, 0, imageRect.size.width, imageRect.size.height); + + progressLayer.position = [self integralPoint:CGPointMake(progressRect.origin.x, progressRect.origin.y)]; + progressLayer.bounds = CGRectMake(0, 0, progressRect.size.width, progressRect.size.height); + progressLayer.progressBorderRadius = _hud.progressBorderRadius; + progressLayer.progressBorderWidth = _hud.progressBorderWidth; + progressLayer.progressRadius = _hud.progressRadius; + progressLayer.progressInset = _hud.progressInset; + progressLayer.theProgress = _progress; + [progressLayer setNeedsDisplay]; + + [CATransaction commit]; + break; + } + + case ATMHudApplyModeUpdate: { + // NSLog(@"ATMHud: ATMHudApplyModeUpdate delegate=%@", delegate); + if ([delegate respondsToSelector:@selector(hudWillUpdate:)]) { + [delegate hudWillUpdate:_hud]; + } + if (blockDelegate) { + blockDelegate(ATMHudActionWillUpdate, _hud); + } + + if (CGPointEqualToPoint(_hud.center, CGPointZero)) { + self.frame = CGRectMake((self.superview.bounds.size.width-targetBounds.size.width)*0.5f, (self.superview.bounds.size.height-targetBounds.size.height)*0.5f, targetBounds.size.width, targetBounds.size.height); + } else { + self.bounds = CGRectMake(0, 0, targetBounds.size.width, targetBounds.size.height); + self.center = _hud.center; + } + + CABasicAnimation *ccAnimation = [CABasicAnimation animationWithKeyPath:@"caption"]; + ccAnimation.duration = 0.001; + ccAnimation.toValue = @""; + ccAnimation.delegate = self; + [captionLayer addAnimation:ccAnimation forKey:@"captionClearAnimation"]; + captionLayer.caption = @""; + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [CATransaction setCompletionBlock:^{ + _backgroundLayer.bounds = targetBounds; - backgroundLayer.position = CGPointMake(0.5*targetBounds.size.width, 0.5*targetBounds.size.height); - backgroundLayer.bounds = targetBounds; + progressLayer.theProgress = _progress; + [progressLayer setNeedsDisplay]; - captionLayer.position = [self sharpPoint:CGPointMake(captionRect.origin.x, captionRect.origin.y)]; - captionLayer.bounds = CGRectMake(0, 0, captionRect.size.width, captionRect.size.height); CABasicAnimation *cAnimation = [CABasicAnimation animationWithKeyPath:@"caption"]; cAnimation.duration = 0.001; - cAnimation.toValue = caption; + cAnimation.toValue = _caption; [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"]; - captionLayer.caption = caption; - - imageLayer.contents = (id)image.CGImage; - imageLayer.position = [self sharpPoint:CGPointMake(imageRect.origin.x, imageRect.origin.y)]; - imageLayer.bounds = CGRectMake(0, 0, imageRect.size.width, imageRect.size.height); - - progressLayer.position = [self sharpPoint:CGPointMake(progressRect.origin.x, progressRect.origin.y)]; - progressLayer.bounds = CGRectMake(0, 0, progressRect.size.width, progressRect.size.height); - progressLayer.progressBorderRadius = p.progressBorderRadius; - progressLayer.progressBorderWidth = p.progressBorderWidth; - progressLayer.progressBarRadius = p.progressBarRadius; - progressLayer.progressBarInset = p.progressBarInset; - progressLayer.theProgress = progress; - [progressLayer setNeedsDisplay]; + captionLayer.caption = _caption; - [CATransaction commit]; - break; - } - - case ATMHudApplyModeUpdate: { - if ([(id)p.delegate respondsToSelector:@selector(hudWillUpdate:)]) { - [p.delegate hudWillUpdate:p]; + if (_showActivity) { + _activity.activityIndicatorViewStyle = _activityStyle; + _activity.frame = CGRectIntegral(activityRect); } - if (CGPointEqualToPoint(p.center, CGPointZero)) { - self.frame = CGRectMake((self.superview.bounds.size.width-targetBounds.size.width)*0.5, (self.superview.bounds.size.height-targetBounds.size.height)*0.5, targetBounds.size.width, targetBounds.size.height); - } else { - self.bounds = CGRectMake(0, 0, targetBounds.size.width, targetBounds.size.height); - self.center = p.center; + CGRect r = self.frame; + [self setFrame:CGRectIntegral(r)]; +#ifdef ATM_SOUND + if (![_hud.updateSound isEqualToString:@""] && _hud.updateSound != NULL) { + [_hud playSound:_hud.updateSound]; } - - CABasicAnimation *ccAnimation = [CABasicAnimation animationWithKeyPath:@"caption"]; - ccAnimation.duration = 0.001; - ccAnimation.toValue = @""; - ccAnimation.delegate = self; - [captionLayer addAnimation:ccAnimation forKey:@"captionClearAnimation"]; - captionLayer.caption = @""; - - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - [CATransaction setCompletionBlock:^{ - backgroundLayer.bounds = targetBounds; - - progressLayer.theProgress = progress; - [progressLayer setNeedsDisplay]; - - CABasicAnimation *cAnimation = [CABasicAnimation animationWithKeyPath:@"caption"]; - cAnimation.duration = 0.001; - cAnimation.toValue = caption; - [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"]; - captionLayer.caption = caption; - - if (showActivity) { - activity.activityIndicatorViewStyle = activityStyle; - activity.frame = [self sharpRect:activityRect]; - } - - CGRect r = self.frame; - [self setFrame:[self sharpRect:r]]; - - if (![p.updateSound isEqualToString:@""] && p.updateSound != NULL) { - [p playSound:p.updateSound]; - } - if ([(id)p.delegate respondsToSelector:@selector(hudDidUpdate:)]) { - [p.delegate hudDidUpdate:p]; - } - }]; - - backgroundLayer.position = CGPointMake(0.5*targetBounds.size.width, 0.5*targetBounds.size.height); - imageLayer.position = [self sharpPoint:CGPointMake(imageRect.origin.x, imageRect.origin.y)]; - progressLayer.position = [self sharpPoint:CGPointMake(progressRect.origin.x, progressRect.origin.y)]; - - imageLayer.bounds = CGRectMake(0, 0, imageRect.size.width, imageRect.size.height); - progressLayer.bounds = CGRectMake(0, 0, progressRect.size.width, progressRect.size.height); - - progressLayer.progressBorderRadius = p.progressBorderRadius; - progressLayer.progressBorderWidth = p.progressBorderWidth; - progressLayer.progressBarRadius = p.progressBarRadius; - progressLayer.progressBarInset = p.progressBarInset; - - captionLayer.position = [self sharpPoint:CGPointMake(captionRect.origin.x, captionRect.origin.y)]; - captionLayer.bounds = CGRectMake(0, 0, captionRect.size.width, captionRect.size.height); - - imageLayer.contents = (id)image.CGImage; - [CATransaction commit]; - break; - } - - case ATMHudApplyModeHide: { - if ([(id)p.delegate respondsToSelector:@selector(hudWillDisappear:)]) { - [p.delegate hudWillDisappear:p]; +#endif + if ([delegate respondsToSelector:@selector(hudDidUpdate:)]) { + [delegate hudDidUpdate:_hud]; } - if (![p.hideSound isEqualToString:@""] && p.hideSound != NULL) { - [p playSound:p.hideSound]; + if (blockDelegate) { + blockDelegate(ATMHudActionDidUpdate, _hud); } - - [UIView animateWithDuration:.1 - animations:^{ - self.alpha = 0.0; - self.transform = CGAffineTransformMakeScale(p.disappearScaleFactor, p.disappearScaleFactor); - } - completion:^(BOOL finished){ - if (finished) { - self.superview.userInteractionEnabled = NO; - self.transform = CGAffineTransformMakeScale(1.0, 1.0); - [self reset]; - if ([(id)p.delegate respondsToSelector:@selector(hudDidDisappear:)]) { - [p.delegate hudDidDisappear:p]; - } - } - }]; - break; + }]; + + _backgroundLayer.position = CGPointMake(0.5f*targetBounds.size.width, 0.5f*targetBounds.size.height); + imageLayer.position = [self integralPoint:CGPointMake(imageRect.origin.x, imageRect.origin.y)]; + + + progressLayer.position = [self integralPoint:CGPointMake(progressRect.origin.x, progressRect.origin.y)]; + + imageLayer.bounds = CGRectMake(0, 0, imageRect.size.width, imageRect.size.height); + progressLayer.bounds = CGRectMake(0, 0, progressRect.size.width, progressRect.size.height); + + progressLayer.progressBorderRadius = _hud.progressBorderRadius; + progressLayer.progressBorderWidth = _hud.progressBorderWidth; + progressLayer.progressRadius = _hud.progressRadius; + progressLayer.progressInset = _hud.progressInset; + + captionLayer.position = [self integralPoint:CGPointMake(captionRect.origin.x, captionRect.origin.y)]; + captionLayer.bounds = CGRectMake(0, 0, captionRect.size.width, captionRect.size.height); + + imageLayer.contents = (id)_image.CGImage; + [CATransaction commit]; + break; + } + + case ATMHudApplyModeHide: { + // NSLog(@"ATMHud: ATMHudApplyModeHide delegate=%@", delegate); + if ([delegate respondsToSelector:@selector(hudWillDisappear:)]) { + [delegate hudWillDisappear:_hud]; + } + if (blockDelegate) { + blockDelegate(ATMHudActionWillDisappear, _hud); + } +#ifdef ATM_SOUND + if (![_hud.hideSound isEqualToString:@""] && _hud.hideSound != NULL) { + [_hud playSound:_hud.hideSound]; } +#endif + //NSLog(@"GOT TO ATMHudApplyModeHide duration=%f delegate=%x _hud=%x", _hud.animateDuration, (unsigned int)delegate, (unsigned int)_hud); + + __weak ATMHudView *weakSelf = self; + [UIView animateWithDuration:_hud.animateDuration + animations:^{ + self.alpha = 0.0; + self.transform = CGAffineTransformMakeScale(_hud.disappearScaleFactor, _hud.disappearScaleFactor); + } + completion:^(BOOL finished){ + // if (finished) Got to do this regardless of whether it finished or not. + { + weakSelf.superview.userInteractionEnabled = NO; + weakSelf.transform = CGAffineTransformMakeScale(1.0f, 1.0f); +#define NO_CRASH + [weakSelf reset]; +#ifdef NO_CRASH + [weakSelf.hud.view removeFromSuperview]; +#else + dispatch_async(dispatch_get_main_queue(), ^ + { + [weakSelf.hud.view removeFromSuperview]; + } ); +#endif + if ([delegate respondsToSelector:@selector(hudDidDisappear:)]) { + [delegate hudDidDisappear:weakSelf.hud]; + } + if (blockDelegate) { + blockDelegate(ATMHudActionDidDisappear, weakSelf.hud); + } + } + }]; + break; + } } } -- (void)show { - [self calculate]; - [self applyWithMode:ATMHudApplyModeShow]; +- (void)show +{ + if (didHide) { + //NSLog(@"ATMHUD SHOW!!!"); + didHide = NO; + [self calculate]; + [self applyWithMode:ATMHudApplyModeShow]; + } else { + //NSLog(@"ATMHUD Asked to show, but already showing!!!"); + } } -- (void)hide { - [self applyWithMode:ATMHudApplyModeHide]; +- (void)hide +{ + if (!didHide) { + didHide = YES; // multiple calls to hide wrecks havoc, might get called in a cleanup routine in user code just to be sure. + //NSLog(@"ATMHUD HIDE!!!"); + [self applyWithMode:ATMHudApplyModeHide]; + } else { + //NSLog(@"ATMHUD Asked to hide, but already hidden!!!"); + } } -- (void)update { +- (void)update +{ [self calculate]; [self applyWithMode:ATMHudApplyModeUpdate]; } -- (void)reset { - [p setCaption:@""]; - [p setImage:nil]; - [p setProgress:0]; - [p setActivity:NO]; - [p setActivityStyle:UIActivityIndicatorViewStyleWhite]; - [p setAccessoryPosition:ATMHudAccessoryPositionBottom]; - [p setBlockTouches:NO]; - [p setAllowSuperviewInteraction:NO]; - // TODO: Reset or not reset, that is the question. - [p setFixedSize:CGSizeZero]; - [p setCenter:CGPointZero]; +- (void)reset +{ + ATMHud *hud = _hud; + if(!hud) return; + +assert([NSThread isMainThread]); + + [hud setCaption:@""]; + [hud setImage:nil]; + [hud setProgress:0]; + [hud setActivity:NO]; + [hud setActivityStyle:UIActivityIndicatorViewStyleWhiteLarge]; + [hud setAccessoryPosition:ATMHudAccessoryPositionBottom]; + [hud setBlockTouches:NO]; + [hud setAllowSuperviewInteraction:NO]; + [hud setFixedSize:CGSizeZero]; + [hud setCenter:CGPointZero]; [CATransaction begin]; [CATransaction setDisableActions:YES]; @@ -564,10 +697,21 @@ - (void)reset { cAnimation.toValue = @""; [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"]; captionLayer.caption = @""; - - [p setShowSound:@""]; - [p setUpdateSound:@""]; - [p setHideSound:@""]; + +#ifdef ATM_SOUND + [hud setShowSound:@""]; + [hud setUpdateSound:@""]; + [hud setHideSound:@""]; +#endif +} + +#pragma mark - + +// Issue #21 - provided by paweldudek +- (void)layoutSubviews +{ + [super layoutSubviews]; + self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; } @end diff --git a/ATMHud_Prefix.pch b/ATMHud_Prefix.pch index 6e5644e..b1401bf 100644 --- a/ATMHud_Prefix.pch +++ b/ATMHud_Prefix.pch @@ -5,4 +5,6 @@ #ifdef __OBJC__ #import #import + + #define ATM_SOUND #endif diff --git a/ATMProgressLayer.h b/ATMProgressLayer.h index 36c12d2..616abe8 100644 --- a/ATMProgressLayer.h +++ b/ATMProgressLayer.h @@ -4,25 +4,29 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import -@interface ATMProgressLayer : CALayer { - CGFloat theProgress; - CGFloat progressBorderWidth; - CGFloat progressBorderRadius; - CGFloat progressBarRadius; - CGFloat progressBarInset; -} +typedef NS_ENUM(NSInteger, ATMHudProgressStyle) { + ATMHudProgressStyleBar, + ATMHudProgressStyleCircle +}; + +@interface ATMProgressLayer : CALayer +@property (nonatomic, assign) ATMHudProgressStyle progressStyle; @property (nonatomic, assign) CGFloat theProgress; @property (nonatomic, assign) CGFloat progressBorderWidth; @property (nonatomic, assign) CGFloat progressBorderRadius; -@property (nonatomic, assign) CGFloat progressBarRadius; -@property (nonatomic, assign) CGFloat progressBarInset; +@property (nonatomic, assign) CGFloat progressRadius; +@property (nonatomic, assign) CGFloat progressInset; + +- (CGSize)progressSize; @end + diff --git a/ATMProgressLayer.m b/ATMProgressLayer.m index 5ea684d..c936c0d 100644 --- a/ATMProgressLayer.m +++ b/ATMProgressLayer.m @@ -4,50 +4,109 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ +#import + #import "ATMProgressLayer.h" +#define PROGRESS_HEIGHT_BAR 10 +#define PROGRESS_WIDTH_BAR 210 +#define PROGRESS_DIMENSION_CIRCLE 40 + @implementation ATMProgressLayer -@synthesize theProgress, progressBorderWidth, progressBorderRadius, progressBarRadius, progressBarInset; -- (void)drawInContext:(CGContextRef)ctx { +- (CGSize)progressSize +{ + if(_progressStyle == ATMHudProgressStyleBar) { + return CGSizeMake(PROGRESS_WIDTH_BAR, PROGRESS_HEIGHT_BAR); + } else { + return CGSizeMake(PROGRESS_DIMENSION_CIRCLE, PROGRESS_DIMENSION_CIRCLE); + } +} + +- (void)setTheProgress:(CGFloat)p +{ + _theProgress = p; + [self setNeedsDisplay]; +} + +- (void)drawInContext:(CGContextRef)ctx +{ UIGraphicsPushContext(ctx); - if (theProgress > 0) { - CGRect rrect = CGRectInset(self.bounds, progressBorderWidth, progressBorderWidth); - CGFloat radius = progressBorderRadius; - - CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); - CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); - - CGContextMoveToPoint(ctx, minx, midy); - CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius); - CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius); - CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius); - CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius); - CGContextClosePath(ctx); - CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1); - CGContextSetLineWidth(ctx, progressBorderWidth); - CGContextDrawPath(ctx, kCGPathStroke); - - radius = progressBarRadius; - - rrect = CGRectInset(rrect, progressBarInset, progressBarInset); - rrect.size.width = rrect.size.width * theProgress; - minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); - miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); - CGContextMoveToPoint(ctx, minx, midy); - CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius); - CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius); - CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius); - CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius); - CGContextClosePath(ctx); - CGContextSetRGBFillColor(ctx,1, 1, 1, 1); - CGContextDrawPath(ctx, kCGPathFill); + if (_theProgress > 0) { + if(_progressStyle == ATMHudProgressStyleBar) { + [self drawBar:ctx]; + } else { + [self drawCircle:ctx]; + } } UIGraphicsPopContext(); } + +- (void)drawBar:(CGContextRef)ctx +{ + CGRect rrect = CGRectInset(self.bounds, _progressBorderWidth, _progressBorderWidth); + CGFloat radius = _progressBorderRadius; + + CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); + CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); + + CGContextMoveToPoint(ctx, minx, midy); + CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius); + CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius); + CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius); + CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius); + CGContextClosePath(ctx); + CGContextSetRGBStrokeColor(ctx,0, 0, 0, 1); + CGContextSetLineWidth(ctx, _progressBorderWidth); + CGContextDrawPath(ctx, kCGPathStroke); + + radius = _progressRadius; + + rrect = CGRectInset(rrect, _progressInset, _progressInset); + rrect.size.width = rrect.size.width * _theProgress; + minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); + miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); + CGContextMoveToPoint(ctx, minx, midy); + CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius); + CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius); + CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius); + CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius); + CGContextClosePath(ctx); + CGContextSetRGBFillColor(ctx,0, 0, 0, 1); + CGContextDrawPath(ctx, kCGPathFill); +} + +- (void)drawCircle:(CGContextRef)ctx +{ + + CGRect rrect = CGRectInset(self.bounds, _progressBorderWidth, _progressBorderWidth); + CGFloat radius = PROGRESS_DIMENSION_CIRCLE/2 - _progressBorderRadius; + + CGFloat midx = CGRectGetMidX(rrect); + CGFloat midy = CGRectGetMidY(rrect); + + CGContextAddArc(ctx, midx, midy, radius, 0, 2.0*M_PI, 1); + CGContextClosePath(ctx); + + CGContextSetRGBStrokeColor(ctx,0, 0, 0, 1); + CGContextSetLineWidth(ctx, _progressBorderWidth); + CGContextDrawPath(ctx, kCGPathStroke); + + CGFloat progressWidth = _progressBorderWidth * 4; + radius -= progressWidth/2; + + CGFloat radians = (2*M_PI*_theProgress); + CGContextAddArc(ctx, midx, midy, radius, -2.0*M_PI/4.0, -2.0*M_PI/4.0 + radians, 0); + + CGContextSetRGBStrokeColor(ctx,0, 0, 0, 1); + CGContextSetLineWidth(ctx, progressWidth); + CGContextDrawPath(ctx, kCGPathStroke); +} + @end diff --git a/ATMSoundFX.h b/ATMSoundFX.h index bf3620f..71b3e8b 100644 --- a/ATMSoundFX.h +++ b/ATMSoundFX.h @@ -4,20 +4,15 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ -#import - @interface ATMSoundFX : NSObject -{ - SystemSoundID _soundID; -} -+ (id)soundEffectWithContentsOfFile:(NSString *)aPath; -- (id)initWithContentsOfFile:(NSString *)path; +- (instancetype)initWithContentsOfFile:(NSString *)path; - (void)play; @end diff --git a/ATMSoundFX.m b/ATMSoundFX.m index 70477d7..51394e9 100644 --- a/ATMSoundFX.m +++ b/ATMSoundFX.m @@ -4,51 +4,54 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ +#import + #import "ATMSoundFX.h" @implementation ATMSoundFX - -+ (id)soundEffectWithContentsOfFile:(NSString *)aPath { - if (aPath) { - return [[[ATMSoundFX alloc] initWithContentsOfFile:aPath] autorelease]; - } - return nil; +{ + SystemSoundID soundID; } -- (id)initWithContentsOfFile:(NSString *)path { - self = [super init]; - - if (self != nil) { +- (instancetype)initWithContentsOfFile:(NSString *)path +{ + if ((self = [super init])) { NSURL *aFileURL = [NSURL fileURLWithPath:path isDirectory:NO]; - if (aFileURL != nil) { + if (aFileURL) { SystemSoundID aSoundID; - OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)aFileURL, &aSoundID); + OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)aFileURL, &aSoundID); if (error == kAudioServicesNoError) { - _soundID = aSoundID; + soundID = aSoundID; } else { - [self release], self = nil; + self = nil; } } else { - [self release], self = nil; + self = nil; } } return self; } --(void)dealloc { - AudioServicesDisposeSystemSoundID(_soundID); - [super dealloc]; +- (void)dealloc +{ + if (soundID) { + // one presumes dealloc called even if init failed, since super succeeded... + AudioServicesDisposeSystemSoundID(soundID); + NSLog(@"SOUND DEALLOC"); + } } --(void)play { - AudioServicesPlaySystemSound(_soundID); +- (void)play +{ + AudioServicesPlaySystemSound(soundID); } -@end \ No newline at end of file +@end diff --git a/ATMTextLayer.h b/ATMTextLayer.h index b36b501..c93a94c 100644 --- a/ATMTextLayer.h +++ b/ATMTextLayer.h @@ -4,17 +4,17 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ +#import +#import #import -@interface ATMTextLayer : CALayer { - NSString *caption; -} - -@property (nonatomic, retain) NSString *caption; +@interface ATMTextLayer : CALayer +@property (nonatomic, strong) NSString *caption; @end diff --git a/ATMTextLayer.m b/ATMTextLayer.m index 9d7be5f..200d276 100644 --- a/ATMTextLayer.m +++ b/ATMTextLayer.m @@ -4,24 +4,20 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import "ATMTextLayer.h" -@implementation ATMTextLayer -@synthesize caption; +//#define DROP_SHADOW -- (id)initWithLayer:(id)layer { - if ((self = [super init])) { - caption = @""; - } - return self; -} +@implementation ATMTextLayer -+ (BOOL)needsDisplayForKey:(NSString *)key { ++ (BOOL)needsDisplayForKey:(NSString *)key +{ if ([key isEqualToString:@"caption"]) { return YES; } else { @@ -29,25 +25,34 @@ + (BOOL)needsDisplayForKey:(NSString *)key { } } -- (void)drawInContext:(CGContextRef)ctx { - UIGraphicsPushContext(ctx); - +- (instancetype)initWithLayer:(id)layer +{ + if ((self = [super init])) { + self.caption = @""; + } + return self; +} + +- (void)drawInContext:(CGContextRef)ctx +{ + UIGraphicsPushContext(ctx); // Makes this contest the current context CGRect f = self.bounds; +#ifdef DROP_SHADOW CGRect s = f; - s.origin.y -= 1; - - [[UIColor blackColor] set]; - [caption drawInRect:f withFont:[UIFont boldSystemFontOfSize:14] lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter]; - - [[UIColor whiteColor] set]; - [caption drawInRect:s withFont:[UIFont boldSystemFontOfSize:14] lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter]; - - UIGraphicsPopContext(); -} +#endif + f.origin.y -= 1; // seems weird, but the text looks a bit better being just a pixel higher! This is how the original code worked. + + UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; + paragraphStyle.alignment = NSTextAlignmentCenter; -- (void)dealloc { - [caption release]; - [super dealloc]; +#ifdef DROP_SHADOW + [_caption drawInRect:s withAttributes:@{ NSFontAttributeName : font, NSParagraphStyleAttributeName : paragraphStyle, NSForegroundColorAttributeName : [UIColor grayColor]}]; +#endif + [_caption drawInRect:f withAttributes:@{ NSFontAttributeName : font, NSParagraphStyleAttributeName : paragraphStyle, NSForegroundColorAttributeName : [UIColor blackColor]}]; + + UIGraphicsPopContext(); } @end diff --git a/Classes/ATMHudAppDelegate.h b/Classes/ATMHudAppDelegate.h index 375eceb..a6dc407 100644 --- a/Classes/ATMHudAppDelegate.h +++ b/Classes/ATMHudAppDelegate.h @@ -4,6 +4,7 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * * This sample project uses the sound @@ -17,7 +18,7 @@ * with kind permission of Joseph Wain. * You can get them here: http://glyphish.com/ * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import @@ -27,8 +28,8 @@ UINavigationController *nav; } -@property (nonatomic, retain) IBOutlet UIWindow *window; -@property (nonatomic, retain) UINavigationController *nav; +@property (nonatomic, strong) IBOutlet UIWindow *window; +@property (nonatomic, strong) UINavigationController *nav; @end diff --git a/Classes/ATMHudAppDelegate.m b/Classes/ATMHudAppDelegate.m index 3f47860..95dfee9 100644 --- a/Classes/ATMHudAppDelegate.m +++ b/Classes/ATMHudAppDelegate.m @@ -4,6 +4,7 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * * This sample project uses the sound @@ -17,12 +18,13 @@ * with kind permission of Joseph Wain. * You can get them here: http://glyphish.com/ * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import "ATMHudAppDelegate.h" #import "DemoViewController.h" + @implementation ATMHudAppDelegate @synthesize window, nav; @@ -30,44 +32,43 @@ @implementation ATMHudAppDelegate #pragma mark Application lifecycle - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - DemoViewController *rvc = [[DemoViewController alloc] init]; + DemoViewController *rvc = [DemoViewController new]; rvc.title = @"atomHUD • Demo"; nav = [[UINavigationController alloc] initWithRootViewController:rvc]; - [rvc release]; window.rootViewController = nav; [self.window makeKeyAndVisible]; - + return YES; } -- (void)applicationWillResignActive:(UIApplication *)application { +- (void)applicationWillResignActive:(UIApplication *)application +{ } -- (void)applicationDidEnterBackground:(UIApplication *)application { +- (void)applicationDidEnterBackground:(UIApplication *)application +{ } -- (void)applicationWillEnterForeground:(UIApplication *)application { +- (void)applicationWillEnterForeground:(UIApplication *)application +{ } -- (void)applicationDidBecomeActive:(UIApplication *)application { +- (void)applicationDidBecomeActive:(UIApplication *)application +{ } -- (void)applicationWillTerminate:(UIApplication *)application { +- (void)applicationWillTerminate:(UIApplication *)application +{ } #pragma mark - #pragma mark Memory management -- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { -} - -- (void)dealloc { - [window release]; - [nav release]; - [super dealloc]; +- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application +{ } - @end + diff --git a/Classes/DemoViewController.h b/Classes/DemoViewController.h index 2066b93..da66726 100644 --- a/Classes/DemoViewController.h +++ b/Classes/DemoViewController.h @@ -4,6 +4,7 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * * This sample project uses the sound @@ -17,31 +18,11 @@ * with kind permission of Joseph Wain. * You can get them here: http://glyphish.com/ * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ -#import #import "ATMHudDelegate.h" @class ATMHud; -@interface DemoViewController : UIViewController { - UITableView *tv_demo; - ATMHud *hud; - - NSArray *sectionHeaders; - NSArray *sectionFooters; - NSArray *cellCaptions; - - BOOL useFixedSize; -} - -@property (nonatomic, retain) UITableView *tv_demo; -@property (nonatomic, retain) ATMHud *hud; - -@property (nonatomic, retain) NSArray *sectionHeaders; -@property (nonatomic, retain) NSArray *sectionFooters; -@property (nonatomic, retain) NSArray *cellCaptions; - -@property (nonatomic, assign) BOOL useFixedSize; - +@interface DemoViewController : UIViewController @end diff --git a/Classes/DemoViewController.m b/Classes/DemoViewController.m index 70de809..471f464 100644 --- a/Classes/DemoViewController.m +++ b/Classes/DemoViewController.m @@ -4,6 +4,7 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * * This sample project uses the sound @@ -17,43 +18,65 @@ * with kind permission of Joseph Wain. * You can get them here: http://glyphish.com/ * - * https://github.com/atomton/ATMHud + * https://github.com/atomton/ATMHud (original) */ #import "DemoViewController.h" #import "ATMHud.h" +#import "ATMHudDelegate.h" #import "ATMHudQueueItem.h" #pragma mark - #pragma mark Private interface -@interface DemoViewController () + +@interface DemoViewController () - (void)basicHudActionForRow:(NSUInteger)row; - (void)advancedHudActionForRow:(NSUInteger)row; - (void)positioningActionForRow:(NSUInteger)row; @end @implementation DemoViewController -@synthesize tv_demo, hud, useFixedSize; -@synthesize sectionHeaders, sectionFooters, cellCaptions; +{ + UITableView *tv_demo; + ATMHud *hud; // never released + ATMHud *hud2; // always released + + NSArray *sectionHeaders; + NSArray *sectionFooters; + NSArray *cellCaptions; + + BOOL useFixedSize; +} + +//@synthesize hud, useFixedSize; +//@synthesize sectionHeaders, sectionFooters, cellCaptions; #pragma mark - #pragma mark View lifecycle -- (id)init { + +- (id)init +{ if ((self = [super init])) { - NSArray *section0 = [NSArray arrayWithObjects:@"Show with caption only", @"Show with caption and activity", @"Show with caption and image", @"Show activity only", @"Play sound on show", nil]; - NSArray *section1 = [NSArray arrayWithObjects:@"Show and auto-hide", @"Show, update and auto-hide", @"Show progress bar", @"Show queued HUD", nil]; - NSArray *section2 = [NSArray arrayWithObjects:@"Accessory top", @"Accessory right", @"Accessory bottom", @"Accessory left", nil]; - NSArray *section3 = [NSArray arrayWithObject:@"Use fixed size"]; + NSArray *section0 = @[@"Show with caption only", @"Show with caption and activity", @"Show with caption and image", @"Show activity only", +#ifdef ATM_SOUND + @"Play sound on show", +#endif + ]; + NSArray *section1 = @[@"Show and auto-hide", @"Show, update and auto-hide", @"Show progress bar", @"Show queued HUD"]; + NSArray *section2 = @[@"Accessory top", @"Accessory right", @"Accessory bottom", @"Accessory left"]; + NSArray *section3 = @[@"Alloc/Release & BlockDel."]; + NSArray *section4 = @[@"Use fixed size"]; - sectionHeaders = [[NSArray alloc] initWithObjects:@"Basic functions", @"Advanced functions", @"Accessory positioning", @"", nil]; - sectionFooters = [[NSArray alloc] initWithObjects:@"Tap the HUD to hide it.", @"Tap to hide is disabled.", @"", [ATMHud buildInfo], nil]; - cellCaptions = [[NSArray alloc] initWithObjects:section0, section1, section2, section3, nil]; + sectionHeaders = @[@"Basic functions", @"Advanced functions", @"Accessory positioning", @"Instantiated and Released", @""]; + sectionFooters = @[@"Tap the HUD to hide it.", @"Tap to hide is disabled.", @"", @"Tap the HUD to hide it.", [ATMHud version]]; + cellCaptions = @[section0, section1, section2, section3, section4]; } return self; } -- (void)loadView { - UIView *baseView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; +- (void)loadView +{ + UIView *baseView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; tv_demo = [[UITableView alloc] initWithFrame:baseView.bounds style:UITableViewStyleGrouped]; tv_demo.delegate = self; @@ -62,91 +85,72 @@ - (void)loadView { UIViewAutoresizingFlexibleHeight); [baseView addSubview:tv_demo]; + self.view = baseView; hud = [[ATMHud alloc] initWithDelegate:self]; - [baseView addSubview:hud.view]; - - self.view = baseView; - [baseView release]; } -- (void)viewDidLoad { +- (void)viewDidLoad +{ + [super viewDidLoad]; + useFixedSize = NO; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ return YES; } -- (void)dealloc { - [tv_demo release]; - [hud release]; - - [cellCaptions release]; - [sectionHeaders release]; - [sectionFooters release]; - - [super dealloc]; +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + //[self tableView: tv_demo didSelectRowAtIndexPath: [NSIndexPath indexPathForRow:2 inSection:1] ]; } #pragma mark - #pragma mark UITableView -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return [sectionHeaders objectAtIndex:section]; + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return sectionHeaders[section]; } -- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { - return [sectionFooters objectAtIndex:section]; +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + return sectionFooters[section]; } -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 4; +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return [cellCaptions count]; } -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - switch (section) { - case 0: - return 5; - break; - - case 1: - return 4; - break; - - case 2: - return 4; - break; - - case 3: - return 1; - break; - - default: - return 0; - break; - } +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [cellCaptions[section] count]; } -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ NSString *ident = @"DefaultCell"; - if (indexPath.section == 3) { + if (indexPath.section == ([cellCaptions count] - 1)) { ident = @"SwitchCell"; } UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ident]; if (cell == nil) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ident] autorelease]; + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ident]; } - if (indexPath.section == 3) { - UISwitch *fsSwitch = [[UISwitch alloc] init]; + if (indexPath.section == ([cellCaptions count] - 1)) { + UISwitch *fsSwitch = [UISwitch new]; [fsSwitch sizeToFit]; fsSwitch.on = useFixedSize; [fsSwitch addTarget:self action:@selector(switchToggled:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView = fsSwitch; - [fsSwitch release]; cell.accessoryType = UITableViewCellAccessoryNone; cell.selectionStyle = UITableViewCellSelectionStyleNone; @@ -156,134 +160,216 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.selectionStyle = UITableViewCellSelectionStyleBlue; } - cell.textLabel.text = [[cellCaptions objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.textLabel.text = cellCaptions[indexPath.section][indexPath.row]; return cell; } -- (void)switchToggled:(UISwitch *)sw { +- (void)switchToggled:(UISwitch *)sw +{ useFixedSize = [sw isOn]; - if (useFixedSize) { - [hud setFixedSize:CGSizeMake(200, 100)]; - } else { - [hud setFixedSize:CGSizeZero]; - } } -- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section == 3) { +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == ([cellCaptions count] - 1)) { return nil; } return indexPath; } -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (useFixedSize) { + [hud setFixedSize:CGSizeMake(200, 100)]; + } else { + [hud setFixedSize:CGSizeZero]; + } + +#pragma mark - +#pragma mark Experiment with different UI values +#pragma mark - + +#if 0 + hud.appearScaleFactor = 0.8f; + hud.disappearScaleFactor = 0.8f; + hud.gray = 0.2f; + hud.alpha = 0.8f; + hud.margin = 10.0f; + hud.padding = 10.0f; + hud.alpha = 0.8f; // DFH: originally 0.7 + hud.gray = 0.2f; // DFH: originally 0.0 + hud.animateDuration = 0.1f; + hud.progressBorderRadius = 8.0f; + hud.progressBorderWidth = 2.0f; + hud.progressBarRadius = 5.0f; + hud.progressBarInset = 3.0f; + hud.accessoryPosition = ATMHudAccessoryPositionBottom; + hud.appearScaleFactor = 0.8; // DFH: originally 1.4f + hud.disappearScaleFactor = 0.8; // DFH: originally 1.4f +#if 1 // these default to these + hud.minShowTime = 0; + hud.center = CGPointZero; + hud.blockTouches = NO; + hud.allowSuperviewInteraction = NO; + hud.shadowEnabled = NO; +#endif + +#endif + switch (indexPath.section) { - case 0: - [self basicHudActionForRow:indexPath.row]; - break; - - case 1: - [self advancedHudActionForRow:indexPath.row]; - break; - - case 2: - [self positioningActionForRow:indexPath.row]; - break; + case 0: + [self basicHudActionForRow:indexPath.row]; + break; + + case 1: + [self advancedHudActionForRow:indexPath.row]; + break; + + case 2: + [self positioningActionForRow:indexPath.row]; + break; + + case 3: + { + hud2 = [ATMHud new]; + [hud2 setCaption:@"Just a simple caption."]; + __weak DemoViewController *weakSelf = self; + hud2.blockDelegate = ^(ATMHudAction msg, ATMHud *h) + { +assert([NSThread isMainThread]); + NSLog(@"MSG %d", (int)msg); + switch(msg) { + case ATMHudActionUserDidTapHud: + [h hide]; + break; + case ATMHudActionDidDisappear: + { +//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^ + { + // All this to avoid Xcode warnigs + DemoViewController *strongSelf = weakSelf; + if(strongSelf) { + NSLog(@"Will dealloc..."); + strongSelf->hud2 = nil; + NSLog(@"DID dealloc"); + } + } +//); + + } break; + default: + break; + } + }; + [hud2 showInView:self.view]; + } break; + } } #pragma mark - #pragma mark Demonstration functions and selectors -- (void)basicHudActionForRow:(NSUInteger)row { +- (void)basicHudActionForRow:(NSUInteger)row +{ + hud.minShowTime = 0; + [hud setBlockTouches:NO]; + switch (row) { - case 0: - [hud setCaption:@"Just a simple caption."]; - break; - - case 1: - [hud setCaption:@"Caption and an activity indicator."]; - [hud setActivity:YES]; - break; - - case 2: - [hud setCaption:@"Caption and an image."]; - [hud setImage:[UIImage imageNamed:@"19-check"]]; - break; - - case 3: - [hud setActivity:YES]; - [hud setActivityStyle:UIActivityIndicatorViewStyleWhiteLarge]; - break; - - case 4: - [hud setCaption:@"Showing the HUD triggers a sound."]; - [hud setShowSound:[[NSBundle mainBundle] pathForResource:@"pop" ofType:@"wav"]]; - break; + case 0: + [hud setCaption:@"Just a simple caption."]; + break; + + case 1: + [hud setCaption:@"Caption and an activity indicator."]; + [hud setActivity:YES]; + break; + + case 2: + [hud setCaption:@"Caption and an image."]; + [hud setImage:[[UIImage imageNamed:@"19-check"] imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate]]; + break; + + case 3: + [hud setActivity:YES]; + //[hud setActivityStyle:UIActivityIndicatorViewStyleWhiteLarge]; + break; +#ifdef ATM_SOUND + case 4: + [hud setCaption:@"Showing the HUD triggers a sound."]; + [hud setShowSound:[[NSBundle mainBundle] pathForResource:@"pop" ofType:@"wav"]]; + break; +#endif } - [hud show]; + [hud showInView:self.view]; } -- (void)advancedHudActionForRow:(NSUInteger)row { +- (void)advancedHudActionForRow:(NSUInteger)row +{ + hud.minShowTime = 0; [hud setBlockTouches:YES]; + switch (row) { - case 0: - [hud setCaption:@"This HUD will auto-hide in 2 seconds."]; - [hud show]; - [hud hideAfter:2.0]; - break; - - case 1: - [hud setCaption:@"This HUD will update in 2 seconds."]; - [hud setActivity:YES]; - [hud show]; - [self performSelector:@selector(updateHud) withObject:nil afterDelay:2.0]; - break; - - case 2: { - NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(tick:) userInfo:nil repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; - [hud setCaption:@"Performing operation..."]; - [hud setProgress:0.08]; - [hud show]; - break; - } - - case 3: { - ATMHudQueueItem *item = [[ATMHudQueueItem alloc] init]; - item.caption = @"Display #1"; - item.image = nil; - item.accessoryPosition = ATMHudAccessoryPositionBottom; - item.showActivity = NO; - [hud addQueueItem:item]; - [item release]; - - item = [[ATMHudQueueItem alloc] init]; - item.caption = @"Display #2"; - item.image = nil; - item.accessoryPosition = ATMHudAccessoryPositionRight; - item.showActivity = YES; - [hud addQueueItem:item]; - [item release]; - - item = [[ATMHudQueueItem alloc] init]; - item.caption = @"Display #3"; - item.image = [UIImage imageNamed:@"19-check"]; - item.accessoryPosition = ATMHudAccessoryPositionBottom; - item.showActivity = NO; - [hud addQueueItem:item]; - [item release]; - - [hud startQueue]; - [self performSelector:@selector(showNextDisplayInQueue) withObject:nil afterDelay:2]; - break; - } + case 0: + [hud setCaption:@"This HUD will auto-hide in 2 seconds."]; + hud.minShowTime = 2; // new way + [hud showInView:self.view]; + //[hud hideAfter:2.0]; // old way + [hud hide]; + break; + + case 1: + [hud setCaption:@"This HUD will update in 2 seconds."]; + [hud setActivity:YES]; + [hud showInView:self.view]; + [self performSelector:@selector(updateHud) withObject:nil afterDelay:2.0]; + break; + + case 2: { + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(tick:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; + [hud setCaption:@"Performing operation..."]; + + hud.progressStyle = ATMHudProgressStyleCircle; + [hud setProgress:0.08]; + + [hud showInView:self.view]; + break; + } + + case 3: { + ATMHudQueueItem *item = [ATMHudQueueItem new]; + item.caption = @"Display #1"; + item.image = nil; + item.accessoryPosition = ATMHudAccessoryPositionBottom; + item.showActivity = NO; + [hud addQueueItem:item]; + + item = [ATMHudQueueItem new]; + item.caption = @"Display #2"; + item.image = nil; + item.accessoryPosition = ATMHudAccessoryPositionRight; + item.showActivity = YES; + [hud addQueueItem:item]; + + item = [ATMHudQueueItem new]; + item.caption = @"Display #3"; + item.image = [UIImage imageNamed:@"19-check"]; + item.accessoryPosition = ATMHudAccessoryPositionBottom; + item.showActivity = NO; + [hud addQueueItem:item]; + + [hud startQueueInView:self.view]; + [self performSelector:@selector(showNextDisplayInQueue) withObject:nil afterDelay:2]; + break; + } } } -- (void)tick:(NSTimer *)timer { +- (void)tick:(NSTimer *)timer +{ static CGFloat p = 0.08; p += 0.01; [hud setProgress:p]; @@ -295,45 +381,52 @@ - (void)tick:(NSTimer *)timer { } } -- (void)resetProgress { +- (void)resetProgress +{ [hud setProgress:0]; } -- (void)updateHud { +- (void)updateHud +{ [hud setCaption:@"And now it will hide."]; [hud setActivity:NO]; [hud setImage:[UIImage imageNamed:@"19-check"]]; + + hud.minShowTime = 2; // new way [hud update]; - [hud hideAfter:2.0]; + [hud hide]; // new way + //[hud hideAfter:2.0]; // old way } -- (void)positioningActionForRow:(NSUInteger)row { - [hud setAccessoryPosition:row]; +- (void)positioningActionForRow:(NSUInteger)row +{ + [hud setAccessoryPosition:(ATMHudAccessoryPosition)row]; switch (row) { - case 0: - [hud setCaption:@"Position: Top"]; - [hud setProgress:0.45]; - break; - - case 1: - [hud setCaption:@"Position: Right"]; - [hud setActivity:YES]; - break; - - case 2: - [hud setCaption:@"Position: Bottom"]; - [hud setImage:[UIImage imageNamed:@"11-x"]]; - break; - - case 3: - [hud setCaption:@"Position: Left"]; - [hud setActivity:YES]; - break; + case 0: + [hud setCaption:@"Position: Top"]; + [hud setProgress:0.45]; + break; + + case 1: + [hud setCaption:@"Position: Right"]; + [hud setActivity:YES]; + break; + + case 2: + [hud setCaption:@"Position: Bottom"]; + [hud setImage:[UIImage imageNamed:@"11-x"]]; + break; + + case 3: + [hud setCaption:@"Position: Left"]; + [hud setActivity:YES]; + break; } - [hud show]; + [hud showInView:self.view]; } -- (void)showNextDisplayInQueue { +- (void)showNextDisplayInQueue +{ static int i = 1; [hud showNextInQueue]; if (i < 3) { @@ -347,8 +440,15 @@ - (void)showNextDisplayInQueue { #pragma mark - #pragma mark ATMHudDelegate -- (void)userDidTapHud:(ATMHud *)_hud { - [_hud hide]; + +- (void)userDidTapHud:(ATMHud *)theHud +{ + [theHud hide]; +} + +- (void)hudDidDisappear:(ATMHud *)theHud +{ + // normally you would release your ivar here, but this app reuses the HUD so it never gets released } #pragma mark - @@ -356,7 +456,8 @@ - (void)userDidTapHud:(ATMHud *)_hud { // Uncomment this method to see a demonstration of playing a sound everytime a HUD appears. /* -- (void)hudDidAppear:(ATMHud *)_hud { +- (void)hudDidAppear:(ATMHud *)_hud +{ NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: @"pop" ofType: @"wav"]; [hud playSound:soundFilePath]; diff --git a/LICENSE b/LICENSE index c6a0ea9..90f3ec3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,10 @@ -Copyright (c) 2010-2011, Marcel Müller (atomcraft)
All rights reserved. +Copyright (c) 2010-2011, Marcel Müller (atomcraft) +Copyright (c) 2012-2014, David Hoerl +All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. • Neither the name of atomcraft nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 8d419eb..3072fee 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,109 @@ ATMHud - Library for the creation of HUDs in iPhone applications ================================================================ I once needed a HUD for one of my iPhone apps, but was unhappy with the currently available libraries on the internet. Therefore, I decided to create my own library. I've released it as a static library last year, but a lot of people wanted to see the source, so here it is. --- Marcel +-- Marcel [original author] + +Heavily modified by D. Hoerl + +# Operation + +Create, configure, then show it. See the Demo app for more detail. + + // Keep a strong ivar reference to it (ie, "ATMHud *hud") + hud = [[ATMHud alloc] initWithDelegate:self]; + // or hud = [ATMHud new]; using the block delegate + + [hud setCaption:@"Caption and an activity indicator."]; + [hud setActivity:YES]; + [hud showInView:self.view]; + ... + [hud hide]; + // when the delegate method tells you it's finished, you can nil the ivar out if you want + hud = nil; + // if you use the block delegate, you can release the hud there (see DemoViewController) + +##**** Original Modifications, David Hoerl 2011-2014 **** + +The reason I adopted this HUD is because it looks so nice, and it offered a wide range of customization options as well as the ability to get a slew of delegate messages as the HUD was presented and dismissed. Along with those you can get messages when the user taps within, or outside, the HUD. + +I needed needed ARC, so I forked the project. My initial changes: + + * ARCified + * Modern syntax, default setters (no @synthesize) + * more of the existing properties exposed along with some new ones + * blockDelegate along with or for use without the traditional 'delegate' callbacks + * sound can be compiled out of the framework if you aren't using it (assuming most do not.) + * converted to build error/warning free on iOS7 (required constant changes, many changes to UIKit extensions to NSString + * 64 bit clean + * handles view rotation (was a bug on original repository, unsure if I fixed it or not) + +##Futures: + +iOS7 circular determinate progress indicator (just ask for it!) + +##History: + +#4.0.0 - 2/15/2016 + + * Adopt more modern look - white with dark objects (text, progress indication, etc) + * Parallax added as a default + * Circular Progess Style Option + * Enums -> NS_ENUM for Swift + * Nullabilty for Swift + +Note: if you used the older code and switch to this version, you may need to do some edits to your project. + +#3.0.0 - 2/20/2014 + + * Added a Podspec to CocoaPods for this version + * Font now uses UIFont ' preferredFontForTextStyle:UIFontTextStyleSubheadline'' + * Drop shadow removed (code still there, you can enable it if desired) for a more iOS7 look + * Modified appearance defaults to + hud.appearScaleFactor = 0.8f; + hud.disappearScaleFactor = 0.8f; + hud.gray = 0.2f; + hud.alpha = 0.8f; + * Rolled in some of the original issues posted to atomcraft/ATMHud + 14 - Gray property to set background color to a gray (not black), and added a setCenter method + 15 - Screenshots in Readme.md + 17 - Different orientation support? (assume this meant a landscape issue) + 18 - use blocks api instead delegate + 21 - Pull Request - Small performance update + 22 - Retain Cycle - changed property to "weak" + 23 - removeViewWhenHidden property added (use ATMHud without a delegate) + * Experiment with various UI option by changing properties in DemoViewController (see pragma) + +#2.x.x - 2011 - 2013 +* various small tweaks, mostly to address Xcode Analyze errors +* 64 bit clean + +#2.0.0 - 2011 +* Forked code +* ARCified + +#1.2 - Original + +The demo project shows of most of the ways you can display the HUD (but not all the UI customization options): + +NOTE: The original author's text follows the screen shots. + +#ScreenShots +![Basic Functions](ScreenShots/BasicFunctions.png) +![Advanced Functions](ScreenShots/AdvancedFunctions.png) +![Simple Caption](ScreenShots/SimpleCaption.png) +![Caption With Activity](ScreenShots/Caption+Activity.png) +![Caption With Image](ScreenShots/Caption+Image.png) +![Activity Only](ScreenShots/JustSpinner.png) +![Caption With Progress Bar](ScreenShots/Caption+ProgressBar.png) +![Fixed Size Caption With Progress Bar](ScreenShots/Caption+ProgressBar_FixedSize.png) + +##***** Below is the original README text ****** + Requirements ------------ - * iOS 4.0 or above + * iOS 4.0 or above * QuartzCore.framework * AudioToolbox.framework (only if you want to use sounds) diff --git a/ScreenShots/AdvancedFunctions.png b/ScreenShots/AdvancedFunctions.png new file mode 100644 index 0000000..297125f Binary files /dev/null and b/ScreenShots/AdvancedFunctions.png differ diff --git a/ScreenShots/BasicFunctions.png b/ScreenShots/BasicFunctions.png new file mode 100644 index 0000000..92bee02 Binary files /dev/null and b/ScreenShots/BasicFunctions.png differ diff --git a/ScreenShots/Caption+Activity.png b/ScreenShots/Caption+Activity.png new file mode 100644 index 0000000..2b92591 Binary files /dev/null and b/ScreenShots/Caption+Activity.png differ diff --git a/ScreenShots/Caption+Image.png b/ScreenShots/Caption+Image.png new file mode 100644 index 0000000..8c571c7 Binary files /dev/null and b/ScreenShots/Caption+Image.png differ diff --git a/ScreenShots/Caption+ProgressBar.png b/ScreenShots/Caption+ProgressBar.png new file mode 100644 index 0000000..6046e5b Binary files /dev/null and b/ScreenShots/Caption+ProgressBar.png differ diff --git a/ScreenShots/Caption+ProgressBar_FixedSize.png b/ScreenShots/Caption+ProgressBar_FixedSize.png new file mode 100644 index 0000000..74b7e72 Binary files /dev/null and b/ScreenShots/Caption+ProgressBar_FixedSize.png differ diff --git a/ScreenShots/Functions.png b/ScreenShots/Functions.png new file mode 100644 index 0000000..449c54a Binary files /dev/null and b/ScreenShots/Functions.png differ diff --git a/ScreenShots/JustSpinner.png b/ScreenShots/JustSpinner.png new file mode 100644 index 0000000..89e5384 Binary files /dev/null and b/ScreenShots/JustSpinner.png differ diff --git a/ScreenShots/SimpleCaption.png b/ScreenShots/SimpleCaption.png new file mode 100644 index 0000000..99750d4 Binary files /dev/null and b/ScreenShots/SimpleCaption.png differ diff --git a/copySpec b/copySpec new file mode 100755 index 0000000..88bf468 --- /dev/null +++ b/copySpec @@ -0,0 +1,5 @@ +#! /bin/ksh + +set -x +cp *.podspec /Volumes/Data/git/Specs/ATMHud/3.0 + diff --git a/main.m b/main.m index 51f704c..dcd637a 100644 --- a/main.m +++ b/main.m @@ -4,6 +4,7 @@ * * Created by Marcel Müller on 2011-03-01. * Copyright (c) 2010-2011, Marcel Müller (atomcraft) + * Copyright (c) 2012-2014, David Hoerl * All rights reserved. * * This sample project uses the sound @@ -21,8 +22,8 @@ int main(int argc, char *argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int retVal = UIApplicationMain(argc, argv, nil, nil); - [pool release]; - return retVal; + @autoreleasepool { + int retVal = UIApplicationMain(argc, argv, nil, nil); + return retVal; + } }