SVProgressHUD (2.0.3) turned out to be like this

There was no time to write. This weekend, take a brief look at some of their own views on SVProgressHUD and insights. In the process of their own feel insist on open source and insist on writing the original article is not easy. Time is the most valuable resource for every programmer.

brief introduction

SVProgressHUD in the development of iOS as a hint of the scene is still very much. Here mainly from the use of the project and the source side of the line analysis and attached to the relevant renderings. Hope to play a role in attracting jade.

Use

SVProgrossHUD is used in a single case, which is used by many third parties. That is, the rapid creation, do not need to manually alloc instantiation.

Use scenarios: a more reasonable scenario is to determine when the user needs to perform the task before the recommendation of other tasks, rather than in the refresh, unlimited slide or send messages and other scenarios.

Common usage is as follows:

[SVProgressHUD show]; dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{/ processing time consuming operation (dispatch_get_main_queue), dispatch_async (^{[SVProgressHUD dismiss];});});

The use of show + + (void); (void) showWithStatus: (NSString*) string; to display the status is not clear, with (void) + showProgress: (CGFloat + progress); (void) showProgress: (CGFloat) progress status: (NSString*) status; to display the state of clear operation, display the progress of the current operation.


Cancel + (void) dismiss + (void) dismissWithDelay: (NSTimeInterval) delay; here by the way dismissWithDelay this method did not pay attention before. You can cancel the delay, so you don’t have to manually use GCD delay to dismiss.


If you want to balance the number of calls, you can use the + (void) popActivity; once the number of calls to match the show will disappear. If there is no match won’t disappear. The source code for the popActivity + (void) {if ([self sharedView].activityCount > 0) {[self} ([self sharedView].activityCount–; if sharedView].activityCount = = 0) {[[self sharedView] dismiss];}} or according to the length of the string to automatically determine the display time. When these methods when the following calls will use this way (void) + showInfoWithStatus: (NSString* + string); (void) showSuccessWithStatus: (NSString*) string; (void) + showErrorWithStatus: (NSString* + string); (void) showImage: (UIImage*) image status: (NSString*) string;


We can customize some of the attributes, such as font size, prompt pictures, etc.. You can customize the following methods: (void) + setDefaultStyle: (SVProgressHUDStyle) style; / / default is + SVProgressHUDStyleLight (void) setDefaultMaskType: (SVProgressHUDMaskType) maskType; / / default is + SVProgressHUDMaskTypeNone (void) setDefaultAnimationType: (SVProgressHUDAnimationType) type; / / default is + SVProgressHUDAnimationTypeFlat (void) setMinimumSize: (CGSize) minimumSize; / / default is CGSizeZero, can be used to avoid resizing for a larger message (void) + setRingThickness: (CGFloat) width; / / default is 2 + Pt (void) setRingRadius: (CGFloat) radius; / / default is 18 + Pt (void) setRingNoTextRadius: (CGFloat) radius; / / Default is 24 + Pt (void) setCornerRadius: (CGFloat) cornerRadius; / / default is 14 + Pt (void) setFont: (UIFont*) font; / / default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] (void) + setForegroundColor: (UIColor*) color; / / default is [UIColor blackColor] only used for SVProgressHUDStyleCustom (void) + setBackgroundColor: (UIColor*) color; is [UIColor / / default whiteColor] only used for SVProgressHUDStyleCustom (void): setBackgroundLayerColor (UIColor*) color is [UIColor colorWithWhite:0; / / default alpha:0.4], only used for SVProgressHUDMaskTypeCustom (void) + setInfoImage: (UIImage*) image; Default is the bundled info image / provided by + Freepik (void) setSuccessImage: (UIImage*) image default is bundled success image; / / from + Freepik (void) setErrorImage: (UIImage*) image default is bundled error image; / / from + Freepik (void) setViewForExtension: (UIView*) view; / / default is nil, only used if #define SV_APP_EXTENSIONS is set (void) + setMinimumDismissTimeInterval: (NSTimeInterval) interval; / / default is 5 + seconds (void) setFadeInAnimationDuration: (NSTimeInterval) duration; / / default is 0.15 + seconds (void) setFadeOutAnimationDuration: (NSTimeInterval) duration; / / default is 0.15 seconds


The default SVProgressHUD two style SVProgressHUDStyleLight SVProgressHUDStyleDark, a white theme, a theme is black if you want to customize some colors by setForegroundColor and setBackgroundColor don’t forget to set the default SVProgressHUDStyleCustom style


Notice that SVProgressHUD uses SVProgressHUDWillAppearNotification SVProgressHUDDidAppearNotification SVProgressHUDWillDisappearNotification four notification letter SVProgressHUDDidDisappearNotification that each notice will pass a userinfo dictionary transfer HUD and key for SVProgressHUDStatusUserInfoKey. When the user touches the tips of the entire screen will be issued SVProgressHUDDidReceiveTouchEventNotification notice will be issued SVProgressHUDDidTouchDownInsideNotification notice when the user directly touch HUD.

Key class

SVProgroessHUD there are four important classes. They are

  • SVPIndefiniteAnimatedView: unlimited rotation view components. Following figure:
SVProgressHUD (2.0.3) turned out to be like this
  • SVProgressAnimatedView: progress view component. The following figure
    SVProgressHUD (2.0.3) turned out to be like this
  • SVProgressHUD: the view shows the control class (we use the two view components through the SVProgressHUD class). Similar to a management class.
  • SVRadialGradientLayer: gradient layer, when we set the mask style SVProgressHUDMaskTypeGradient, you need to use this layer. Imitate the background effect of system UIAlterView.
SVProgressHUD (2.0.3) turned out to be like this
  • SVProgressHUD.bundle: This is a picture of some of the resources file

Key class analysis

SVPIndefiniteAnimatedView

On this category, the main thing is to say that if an unlimited load of the animation. As shown above. Principle is not difficult, I give this a map, we should understand.

SVProgressHUD (2.0.3) turned out to be like this
  • The principle is to constantly rotate a picture with a gradient color, and then use the mask to cover the unnecessary parts (combined with the use of layer).

Here we have to mention the iOS animation in CALayer and Mask. Common scene is the combination of CAShapeLayer and mask.

A layer whose alpha channel is / used as a mask to select between the layer's background and the result of * compositing the layer's * contents with its filtered background. Defaults to nil. When used as a mask the layer's `compositingFilter'* and backgroundFilters' * properties are ignored. When, setting the mask to a new layer the * new layer must. Have a nil superlayer otherwise the behavior is * undefined. Nested masks (mask layers with their own masks) are * unsupported. / @property (nullable, strong) CALayer *mask;

The above is a description of the CALayer header file about mask, mask actually layer content.
if we put the mask is transparent, actually see the layer is completely transparent, that is, only the contents of the opaque part of the mask and layer overlay will show. The following figure:

SVProgressHUD (2.0.3) turned out to be like this

There are many very cool animation effects are achieved by. For example, the following

SVProgressHUD (2.0.3) turned out to be like this
SVProgressHUD (2.0.3) turned out to be like this

There are also Twitter startup effect

  • code snippet
/ / initialization, parameter setting of _indefiniteAnimatedLayer = [CAShapeLayer layer]; _indefiniteAnimatedLayer.contentsScale [[UIScreen mainScreen] = scale]; _indefiniteAnimatedLayer.frame = CGRectMake (0.0F, 0.0F, arcCenter.x*2, arcCenter.y*2); _indefiniteAnimatedLayer.fillColor [UIColor = clearColor].CGColor; _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor; _indefiniteAnimatedLayer.lineWidth = self.strokeThickness; _indefiniteAnimatedLayer.lineCap = kCALineCapRound; _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel; _indefiniteAnimatedLayer.path = smoothedPath.CGPath; / / initialize mask, *maskLayer = [CALayer CALayer read picture from the resource pool Layer]; NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; NSURL *url = [bundle URLForResource:@ "SVProgressHUD" withExtension:@ "bundle"]; NSBundle *imageBundle = [NSBundle bundleWithURL:url]; NSString *path = [imageBundle pathForResource:@ "angle-mask" ofType:@ "PNG"]; / / a majority of the usage are similar, the picture as the maskLayer contents maskLayer.contents (__bridge = ID) [[UIImage imageWithContentsOfFile:path] CGImage]; maskLayer.frame = _indefiniteAnimatedLayer.bounds; _indefiniteAnimatedLayer.mask = maskLayer;

Began to do animation, animation is divided into two parts, one is the image rotation, one is the animation group

  • Rotate animation
/ / set animation delay and the type of NSTimeInterval animationDuration = 1; CAMediaTimingFunction = *linearCurve [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; CABasicAnimation *animation [CABasicAnimation animationWithKeyPath:@ = "transform.rotation"]; / / value type ID type animation.fromValue (ID) = 0; animation.toValue = @ (M_PI*2); animation.duration = animationDuration; animation.timingFunction = linearCurve; / / this parameter do not forget, is to keep the animation made last night after the animation is animation.removedOnCompletion = NO; animation.repeatCount = INFINITY; animation.fillMode = kCAFillModeForwards; anim Ation.autoreverses = NO; / / the animation will be added to mask [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@ "rotate"];

By rotating the animation we see is

SVProgressHUD (2.0.3) turned out to be like this

Then take a look at the animation group

/ / create animation group, and set the relevant attribute CAAnimationGroup *animationGroup animation] = [CAAnimationGroup; animationGroup.duration = animationDuration; animationGroup.repeatCount = INFINITY; animationGroup.removedOnCompletion = NO; animationGroup.timingFunction = linearCurve; *strokeStartAnimation = [CABasicAnimation CABasicAnimation / / strokeStart animation animationWithKeyPath:@ "strokeStart"]; strokeStartAnimation.fromValue = @0.015; strokeStartAnimation.toValue = @0.515; *strokeEndAnimation = CABasicAnimation / [CABasicAnimation / strokeEnd animation animationWithKeyPath:@ "strokeEnd"]; strokeEndAnimation.fromValue = @0.485; strokeEndAnimati On.toValue = @0.985; / / will be added to the animation animation group animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation]; [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@ "progress"];

Animation effects

SVProgressHUD (2.0.3) turned out to be like this

Let’s look at the relationship between numbers

StrokeStartAnimation.fromValue = @0.015; strokeStartAnimation.toValue = @0.515; strokeEndAnimation.fromValue = @0.485; strokeEndAnimation.toValue = @0.985;

Some rules. This will change the value of strokeStart and strokeEnd and make the difference between a constant. What we are seeing is the effect of a continuous white hole. Personally feel that this effect is to think of clever

Effects of changing strokeEnd parameters

StrokeEndAnimation.fromValue = @0.285; strokeEndAnimation.toValue = @0.785;
SVProgressHUD (2.0.3) turned out to be like this
  • Other

Other worthy of learning should be used to calculate the lazy loading method. Easy to manage the code and clear the logical relationship. Rewrite the property of the setter method, the setter method and the completion of this property related to some of the assignment, the logic to determine the operation. For example:

- (void) setRadius: (CGFloat radius) {if (radius! = _radius) {_radius = radius; / / related logic in the setter method, [_indefiniteAnimatedLayer removeFromSuperlayer]; _indefiniteAnimatedLayer = nil; if (self.superview) {self}}} [layoutAnimatedLayer];

SVProgressAnimatedView

This is used to deal with the progress of the view component, the principle of progress is also very simple, that is, constantly changing the value of strokeEnd.
look at the.H file

@interface SVProgressAnimatedView: UIView / @property (nonatomic, assign) radius of CGFloat radius; / / @property thickness (nonatomic, assign) CGFloat strokeThickness; / / progress indicator color @property (nonatomic, strong) UIColor *strokeColor; / / the current progress, @property (nonatomic, assign) CGFloat strokeEnd; @end

.m file is roughly the same as SVIndefiniteAnimatedView. Using lazy loading, add layer to the willMoveToSuperview method. The key to achieving progress is to rewrite the strokeEnd setter method

- (void) setStrokeEnd: (CGFloat strokeEnd) {_strokeEnd = strokeEnd; / / change the end position of _ringAnimatedLayer.strokeEnd = _strokeEnd;}

Progress of the effect of writing 0.4

SVProgressHUD (2.0.3) turned out to be like this

By the way, the default value for storkeStart is 0. So it started right over there.

SVProgressHUD

The role of this class is to think about the role of the management class, to be responsible for interacting with the outside and to call the view component. Important logical judgment.

.h file

Extern correlation

Take a look at the use of.H file extern

Extern NSString * const SVProgressHUDDidReceiveTouchEventNotification NSString * const; extern SVProgressHUDDidTouchDownInsideNotification; extern NSString SVProgressHUDWillDisappearNotification extern NSString * * const; const SVProgressHUDDidDisappearNotification; extern NSString SVProgressHUDWillAppearNotification extern NSString * * const; const SVProgressHUDDidAppearNotification; extern NSString * const SVProgressHUDStatusUserInfoKey;

Associated with extern and const, static, etc.. Expand below

Const is the best understood, modified things cannot be modified. The pointer type according to the different locations can be understood as 3 types: after const
initialization cannot be assigned, the objects can be any object, the object variable.
NSString * const pT1
; after the pointer is initialized to a constant can be assigned, namely point to other constants, the pointer itself can be modified to not change the value of
const NSString * pT2; a constant pointer to a constant
const NSString * const pT3; extern
is equivalent to C, the definition of global variables,
statement extern const NSString AA
const NSString AA;
= @ “ABC”; static
is equivalent to C, will be limited to the scope of variables in this document?
is different from Java C++ inside the class variables, OC no class variables

Conclusion static
/ / static variables belong to this category, different classes corresponding to different objects is shared
/ / static variable with the same class of all objects, only a const
/ / static initialization of const variables with static I conclusion, just can’t change, but the different object
/ / extern const variables only one object, the definition of
/ / standard method of constant extern mean that this variable is defined, you are only responsible for the use on the line

Typedef NS_ENUM

The definition of common enumeration, pay attention to the command, the ***Type value of the named ***TypeLight

UI_APPEARANCE_SELECTOR

UI_APPEARANCE_SELECTOR: keyword is the appearance of the properties are used, with a simple example of its role.
[[UIBarButtonItem setTintColor:[UIColor appearance]; you can customize the application of all the bar button color for redColor redColor]]. Without this UI_APPEARANCE_SELECTOR, as long as a control to modify. That is, through the UI_APPEARANCE_SELECTOR can be set to control the color of the bulk.

Insight can be used to customize the view using the UIAppearance protocol

When I’m working on a public component, be sure to remember what the default value is.

Class method

There are two main classes of methods, one is set*** one is show**. The former is used to set the appearance style, which is used directly.
example:

  • Set**
(void) + setDefaultStyle: (SVProgressHUDStyle) style; / / default is + SVProgressHUDStyleLight (void) setDefaultMaskType: (SVProgressHUDMaskType) maskType; / / default is + SVProgressHUDMaskTypeNone (void) setDefaultAnimationType: (SVProgressHUDAnimationType) type; / / default is SVProgressHUDAnimationTypeFlat
  • Show**
Show + + (void); (void) showWithMaskType: (SVProgressHUDMaskType) maskType (__attribute__ (deprecated ("Use show and setDefaultMaskType: instead."))); (void) + showWithStatus: (NSString* + status); (void): showWithStatus (NSString*) status maskType: (SVProgressHUDMaskType) maskType (__attribute__ (deprecated ("Use showWithStatus: and setDefaultMaskType: instead.")));

Here’s a note on how to mark the way the method expires maskType __attribute__ (deprecated (Use showSuccessWithStatus: setDefaultMaskType: instead.))

.m file

.m file contains the contents of the entire project is the most complex or the most need to comb and worth learning. The following focuses on the contents of the.M file.

Definition of constants

Define and statc on the definition of const constant difference, here is not to say. Mainly to remind you, try to use statci const to define more in line with the style bar. For example
static CGFloat SVProgressHUDParallaxDepthPoints = 10 const;

The use of readonly and getter

Although there are some trouble with this usage, it is recommended for the programmer who has obsessive-compulsive disorder

@property (nonatomic, readonly, getter = isClear) BOOL clear;

Getter method

- (BOOL isClear) {return (self.defaultMaskType = = SVProgressHUDMaskTypeClear self.defaultMaskType = = SVProgressHUDMaskTypeNone ||});

Definition of private methods in advance, that is, the outside world can not directly call the instance method

This habit is a quick way to understand what kind of methods and methods to classify the entire class. For example:

- (void) setStatus: (NSString*) status; (void) - setFadeOutTimer: (NSTimer*) - (void) timer; registerNotifications; notificationUserInfo; - (NSDictionary*) - (void) positionHUD: (NSNotification*) notification; (void) - moveToPoint: (CGPoint) newCenter rotateAngle: (CGFloat) angle; (void) - overlayViewDidReceiveTouchEvent: (ID sender forEvent: (UIEvent*) event);

This is more organized, the definition of the private method is the extension of the class.

Use singleton

Some of the common UI on the third sides are called by the class method, and the overall situation can only use an instance of the object can be maintained.

+ (SVProgressHUD*) sharedView static dispatch_once_t static SVProgressHUD {once; *sharedView; #if! Defined (SV_APP_EXTENSIONS) / / create a singleton object dispatch_once (& once, sharedView = [[self alloc] initWithFrame:[[[UIApplication ^{sharedApplication] delegate] window].bounds];}); #else dispatch_once (& once, sharedView [[self alloc] initWithFrame:[[UIScreen mainScreen] ^{= bounds]];}); #endif return sharedView;}

Parameterization of show method

On the parameterization of the method is to achieve the code reuse. Because there is the same logic, the same part is extracted, and different parts are controlled by introducing different parameters to achieve the reuse of the code. In practice, this is also very important.

After finishing, finally all ended up calling the show** method is called one way only two + (void) showProgress: (float) progress status: (NSString*) and status + (void) showImage: (UIImage*) image status: (NSString*) status

  • ShowProgress: (float) progress status: (NSString*) status

When an infinite rotation is displayed, it will be sent to the progrerss = -1 to show the progress of the style.

(void) showWithStatus: (NSString*) status {[self sharedView]; [self showProgress:SVProgressHUDUndefinedProgress status:status];}

The SVProgressHUDUndefinedProgress here is actually a constant. Its definition is static const SVProgressHUDUndefinedProgress = -1 = CGFloat;

It is important to note that the mask style is not set by parameter passing but by setting properties.

(void) + showProgress: (float) progress maskType: (SVProgressHUDMaskType maskType) {SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; [self setDefaultMaskType:maskType]; [self showProgress:progress]; / / return to the default mask style [self setDefaultMaskType:existingMaskType] display finished;}

I have a simple analysis of the reason why you don’t pass a parameter to the mask style. It should be to ensure that the style of the next mask is still the default style after each display. You can see that each call after the show** will be restored to the default value of mask.

  • (void) showImage: (UIImage*) image status: (NSString*) status

This method will automatically disappear show** will eventually call the method, such as

(void) + showInfoWithStatus: (NSString* + status); (void) showInfoWithStatus: (NSString*) status maskType: (SVProgressHUDMaskType) maskType (__attribute__ (deprecated ("Use showInfoWithStatus: and setDefaultMaskType: instead."))); (void) + showSuccessWithStatus: (NSString* + status); (void) showSuccessWithStatus: (NSString*) status maskType: (SVProgressHUDMaskType) maskType __attribute__ ((deprecated ("Use showSuccessWithStatus: and setDefaultMaskType: instead."))); (void) + showErrorWithStatus: (NSString* + status); (void) showErrorWithStatus: (NSString*) status maskType: (SVProgressHUDMaskType) maskType (__attribute__ (deprecated ("Use showErrorWithStatus: and setDefaultMaskType: instead."))); / / shows a image + status, use 28x28 white PNGs (void) + showImage: (UIImag E*) image status: (NSString*) status; (void) + showImage: (UIImage*) image status: (NSString*) status maskType: (SVProgressHUDMaskType) maskType (__attribute__ (deprecated ("Use showImage:status: and setDefaultMaskType: instead.")));

UIAccessibility

The UIAccessibility protocol is used to let the external program to understand the situation of their own body. Accessibility is an interactive protocol based on query < -> response; notification < -> protocol for monitoring model. External procedures through the query to obtain the APP response, so as to understand the procedure. In addition, by monitoring the message from the APP, to inform the user of the current state.

  • 1 commonly used protocols and elements include:

UIAccessibility, protocol, core protocol.
UIAccessibilityAction, protocol, add behavior protocol. UIAccessibilityElement, class.
UIAccessibilityContainer, protocol, container protocol.

  • 2 commonly used function UIAccessibilityPostNotification.

You can see SVProgressHUD support UIAccessibility

Accessibility support / / self.accessibilityIdentifier = @ @ self.accessibilityLabel = "SVProgressHUD"; "SVProgressHUD"; self.isAccessibilityElement = YES;

Look at the official introduction

UIAccessibility UIAccessibility is implemented on all / standard UIKit views and controls so that assistive applications can present them to users with disabilities. Custom items in a user interface should override aspects of UIAccessibility to supply details where the default value is incomplete. For example, a UIImageView subclass may need to override accessibilityLabel, but it does not need to override accessibilityFrame. A completely custom subclass of UIView might need to override all of the UIAccessibility methods except accessibilityFrame..

ShowProgress: (float) progress status: (NSString*) status

We all know about the operation of UI need to be placed in the main thread. The general way to pass GCD is as follows:

Dispatch_async (dispatch_get_main_queue), (^{});

But SVProgressHUD is used inside the NSOperation to achieve,

[[NSOperationQueue mainQueue] addOperationWithBlock:^{}];

This also gives us another way to get back to the main thread. ?

Strong & weak

__weak SVProgressHUD *weakSelf self [[NSOperationQueue mainQueue] addOperationWithBlock:^{__strong = SVProgressHUD; *strongSelf = weakSelf; if (strongSelf) {/ / Update / Check view hierachy to ensure the HUD is visible [strongSelf updateViewHierachy];......

The above code is picked from source code, can see in order to prevent __weak SVProgressHUD *weakSelf = self in block outside the circular reference; and the block inside __strong SVProgressHUD with *strongSelf = weakSelf; the beginning to understand this usage is seen from the AFNetWorking source code. In order to ensure that in the implementation of block weakSelf also exists (because it may delay the call), so the need to use __strong in the block in a modified weakSelf.

View display logic

In order to better illustrate the problem, I directly in the source code to facilitate notes.

[[NSOperationQueue mainQueue] addOperationWithBlock:^{__strong SVProgressHUD *strongSelf = weakSelf; / / logical, need to determine whether there are if (strongSelf) {/ / update and check the view hierarchy to ensure the SVProgressHUD visible [strongSelf updateViewHierachy]; / / imageView reset and disappearing time. To prevent the call before, using the last existing style set strongSelf.imageView.hidden = YES; strongSelf.imageView.image = nil; if (strongSelf.fadeOutTimer) {strongSelf.activityCount} = 0; strongSelf.fadeOutTimer = nil; / / update statusLabel display content and display the progress of strongSelf.statusLabel.text = status; strongSelf.progress = progress; / / to determine the correct style, according to the progersss value when progress> =0, shows the progress of style, when progress = -1 for if style of unlimited rotation (Progress > = 0) {/ / prevent last for infinite rotating style leads to overlapping [strong Self cancelIndefiniteAnimatedViewAnimation]; / / add a progress view to hudview, and set the current [strongSelf.hudView addSubview:strongSelf.ringView] and [strongSelf.hudView addSubview:strongSelf.backgroundRingView]; rage; strongSelf.ringView.strokeEnd = progress; / / update activityCount if (Progress = = 0) {strongSelf.activityCount++};} else {/ / last prevent the progress of an led to overlapping [strongSelf cancelRingLayerAnimation]; / / add unlimited rotating view to hudview [strongSelf.hudView addSubview:strongSelf.indefiniteAnimatedVi Ew]; if ([strongSelf.indefiniteAnimatedView respondsToSelector:@selector (startAnimating)] [strongSelf.indefiniteAnimatedView (ID)) {startAnimating]}; strongSelf.activityCount++;} / / display text information [strongSelf showStatus: status];}}];

A rough idea. To display the text of the logic and display the progress of the roadbed and the rotation of the separation to achieve. Because the logic of the display text is public.

It is important to note that there is a method to update the view hierarchy in the [strongSelf code because updateViewHierachy]. is likely to be changed at run time, such as runtime. So every time you need to update the view level, to be able to show.

Update prompt text showStatus: (NSString*) status

Or look at the code

– (void) showStatus: (NSString* status) {/ / frame and location update, because frame is more status to determine the postion parameters according to the control. [self updateHUDFrame]; [self positionHUD:nil] accesibilty; / / update and whether you can click on the if (self.defaultMaskType! = SVProgressHUDMaskTypeNone) {self.overlayView.userInteractionEnabled = YES; self.accessibilityLabel = status; self.isAccessibilityElement = YES;} else {self.overlayView.userInteractionEnabled = NO; self.hudView.accessibilityLabel = status; self.hudView.isAccessibilityElement = YES; self.overlayView.backgroundColor = clearColor] / [UIColor}; according to the criterion of alpha is visible (if self.alpha! = 1.0F || self.hudView.alpha! = 1.0F) {/ / if not visible before issued SVProgressHUDWillAppearNotification notice, immediately told the show [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillAppearNotification object:self userInfo:[self notificationUserInfo]] self.hudView.transform = CGAffineTransformScale; / / zoom effect (self.hudView.transform, 1.3, 1.3); / / initial value processing of iOS7 and above will not change the transparency of UIToolbar response self.alpha = 0.0F; self.hudView.alpha = 0.0F; / / block and complete definition of animation animation block __weak SVProgressHUD *weakSelf = self; __block void (^animationsBlock) (void __strong SVProgressHUD ^{) = *strongSelf = weakSelf; If (strongSelf HUD to finish) {/ / Shrink pop up animation strongSelf.hudView.transform = CGAffineTransformScale (strongSelf.hudView.transform, 1/1.3f, 1/1.3f); strongSelf.alpha = 1.0F; strongSelf.hudView.alpha = 1.0F;}}; __block void (^completionBlock) = __strong (void) ^{SVProgressHUD *strongSelf = weakSelf; if (strongSelf) {/ / / Register observer < => we now have to handle orientation changes etc. [strongSelf registerNotifications] notification to inform; / / Post user [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidAppearNotif Ication object:strongSelf userInfo:[strongSelf notificationUserInfo]];} / / update accesibilty UIAccessibilityPostNotification (UIAccessibilityScreenChangedNotification, Nil); UIAccessibilityPostNotification (UIAccessibilityAnnouncementNotification, status);}; if (self.fadeInAnimationDuration > 0) {/ / if you set the time for animation animation [UIView animateWithDuration:self.fadeInAnimationDuration delay:0 options: (UIViewAnimationOptions) (UIVie WAnimationOptionAllowUserInteraction UIViewAnimationCurveEaseOut UIViewAnimationOptionBeginFromCurrentState | |) animations:^{(animationsBlock);} completion:^ (BOOL finished) {completionBlock (else);}];} {/ / not set time (animationsBlock); completionBlock animation ();} / / update the view hierarchy, then view frame and view the various attributes, tell the system slightly to redraw [self setNeedsDisplay];}}

Write later…

I really did not expect to understand the things they write out so much trouble, so that they write out to share the time really good time. This text itself is also a little bit of time together.

I have always wanted to do a series of source code analysis, not long ago to see the GitHub has a similar project. Some touch, sometimes a lot of their own ideas and the actual time to do little. In general, I sum up the analysis of open source code is not difficult, it is difficult to write a good article.

May be some rough analysis. But it is also a word to write a word. Stick to it!!

There was no time to write. This weekend, take a brief look at some of their own views on SVProgressHUD and insights. In the process of their own feel insist on open source and insist on writing the original article is not easy. Time is the most valuable resource for every programmer.

自己也一直想做一个源码分析的系列,前不久看到了github上已经有人有类似的项目。有些触动,有时候自己想法很多而实际动手去做的时间却很少。总的说来自己总结出,分析开源代码不难,难的是如果写好分析文章。

可能分析得有些粗糙。不过也是自己一个字一个字写出来的。坚持下去吧!!