Content source by

Whenever a project is updated, users are often prompted with a mask for the use of new functionality.

To avoid tedious operations, encapsulate the function module. The following share their own packaging process, can be used as a follow-up to the idea of custom control packaging, designed to help the low degree of packaging friends.




Bootstrap example, image from net.png

Considering the requirements, in order to facilitate processing, guide map naming usually has certain rules, such as: guide_1, guide_2, etc., but due to the need for screen adaptation, the design will provide 3.5, 4, 4.7, 5.5 inch renderings, that is to say, each picture needs to correspond to four screen sizes. Therefore, in real project development, the images that need to be adapted are usually named guide_1_iphone5, guide_1_iphone6, guide_1_iphone6p, etc.

For this requirement, we can add a category for UIImage. When UIImage calls the imageAdaptiveNamed method, we can add the device identifier as follows:

+ (instancetype)imageAdaptiveNamed:(NSString*)imagename { NSString *realImageName = imagename; If (IS_iPHONE4) {realImageName = [NSString stringWithFormat:@"%@_iphone4",realImageName]; } if (IS_iPHONE5) {realImageName = [NSString stringWithFormat:@"%@_iphone5",realImageName]; } if (IS_iPHONE6) {realImageName = [NSString stringWithFormat:@"%@_iphone6",realImageName]; } if (IS_iPHONE6P) {realImageName = [NSString stringWithFormat:@"%@_iphone6p",realImageName]; } return [self imageNamed:realImageName]; }Copy the code

It is recommended to use [UIDevice currentDevice].mode for device identification, for example

#define IS_iPHONE6 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? (CGSizeEqualToSize(CGSizeMake(750, 1334),[[UIScreen mainScreen] currentMode].size)): NO)Copy the code

Next we create a custom class that inherits from UIView, and we want to leak out methods so that the programmer calling the method just passes the generic name and number of images for the bootmask image.

The first thing that comes to mind is a method that extends the parameters of a custom View based on init as follows:

- (instancetype) initWithImageName: (nsstrings *) imageName imageCount (NSInteger) imageCount;Copy the code

But it’s not good enough. The custom class needs to be more compact for the caller to use, so we’ll convert this method to a class method

+ (instancetype)sureGuideViewWithImageName:(NSString*)imageName
                                imageCount:(NSInteger)imageCount;Copy the code

The corresponding implementation is as follows. Here, the generic name and number of pictures can be used globally, so they are declared as attributes.

// Mask image generic name, such as guide@property (nonatomic, copy) NSString *imageName; @property (nonatomic, assign) NSInteger imageCount;Copy the code
/ / to be leakage method + (instancetype) sureGuideViewWithImageName: (nsstrings *) imageName imageCount: (NSInteger) imageCount {return [[the self  alloc]initWithImageName:imageName imageCount:imageCount]; } // initialize operation - (instancetype)initWithImageName:(NSString*)imageName imageCount:(NSInteger)imageCount{if (self = [super init]) { _imageName = imageName; _imageCount = imageCount; [self createUI]; } return self; }Copy the code

Next is to create the corresponding picture.

- (void)createUI {
    self.backgroundColor = [UIColor clearColor];
    self.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    if (_imageCount) {
        for (NSInteger i = 0; i < _imageCount; i++) {
            NSString *realImageName = [NSString stringWithFormat:@"%@_%ld",_imageName,i + 1];
            UIImage *image = [UIImage imageAdaptiveNamed:realImageName];
            UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
            imageView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
            imageView.userInteractionEnabled = YES;
            imageView.tag = 1000 + i;
            [self addSubview:imageView];
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(touchImageView:)];
            [imageView addGestureRecognizer:tap];
        }
    }
    [self show];
}Copy the code

After the above operations, you can change the general name of the passed mask image, such as guide->guide_1_iphone6, etc. If you need to handle the event after the last click, you can call back through Block or proxy.

- (void)touchImageView:(UITapGestureRecognizer*)tap { UIImageView *tapImageView = (UIImageView*)tap.view; // Remove [tapImageView removeFromSuperview]; If (tapImageView.tag-1000 == 0) {// Last line if (self.lastTapBlock) {self.lastTapBlock(); } [self hide]; }}Copy the code

Finally, there is the implicit problem of controlling it. For bootstrapped interfaces, which are usually loaded onto UIWindow rather than view controllers, declare show and hide methods, respectively.

// display - (void)show {[UIApplication sharedApplication]. StatusBarHidden = YES; AppDelegate *appDel = (AppDelegate*)[UIApplication sharedApplication].delegate; [appDel.window addSubview:self]; }Copy the code
// Hide - (void)hide {[UIApplication sharedApplication]. StatusBarHidden = NO; [self removeFromSuperview]; }Copy the code

The boot mask is usually displayed for the first time the user enters the App, so we can do this simply by using NSUserDefaults. Leave out parameters in. H.m respectively

//.h
extern NSString *const SureShouldShowGuide;
//.m
NSString *const SureShouldShowGuide = @"SureShouldShowGuide";Copy the code

This can be seen in why macro definitions should be avoided as much as possible, and why it’s easy for others to get started quickly.

+ (BOOL)shouldShowGuider {NSNumber *number = [[NSUserDefaults standardUserDefaults]objectForKey:SureShouldShowGuide]; If ([number isEqual:@200]) {// Return NO; } else {/ / value does not exist, and assignment to [[NSUserDefaults standardUserDefaults] setObject: @ 200 forKey: SureShouldShowGuide]; [[NSUserDefaults standardUserDefaults]synchronize]; return YES; }}Copy the code

At this point, the mask boot page we need is wrapped. The call is also very succinct:

/ / determine whether shows guide page if ([SureGuideView shouldShowGuider]) {/ / display [SureGuideView sureGuideViewWithImageName: @ "guide" imageCount:3]; }Copy the code

This example is more basic, but the understanding that regards as package train of thought still has profit somewhat, hope to help somewhat to everybody!

Demo Download link

Once and for all, iOS boot mask packaging process demo🔗