異常なインターフェース、空白のページや他のコントロールを示唆しLQAbnormalView

LQAbnormalView.hファイル

//
//  LQAbnormalView.h
//  test
//
//  Created by starxin on 2019/5/30.
//  Copyright © 2019 starxin. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

/**
 异常界面事件回调

 @param idx -1:触摸回调,必须设置allowTouchCallback=YES,其它按照按钮的从左到右的顺序从0递增
 */
typedef void (^LQAbnormalEventBlock)(NSInteger idx);

///异常控件:比如数据请求失败空白页面、无权限异常页面等。
///内部控件排序从上到下:图片、文本、子文本、按钮,若都没有则整个控件高度为0
///所有的文本都是居中显示,文本以及子文本的marginLeftXText,marginRightXText,marginLeftXSubText,marginRightXSubText仅用于计算最大的宽度
@interface LQAbnormalView : UIView

#pragma mark --- 图片属性设置
///图片名称,以图片有二进制数据为创建图片控件的依据
@property (nonatomic, copy, readwrite) NSString* imgName;
///图片宽度,默认值图片的实际宽度
@property (nonatomic, assign, readwrite) CGFloat imgWidth;
///图片高度,默认值图片的实际高度
@property (nonatomic, assign, readwrite) CGFloat imgHeight;
///图片显示模式,默认UIViewContentModeScaleAspectFit
@property (nonatomic, assign, readwrite) UIViewContentMode imgContentMode;
///图片的背景颜色,默认是无色
@property (nonatomic, strong, readwrite) UIColor* imgBackgroundColor;

#pragma mark --- 文本内容属性设置
///文本内容,若同时设置了富文本,则富文本优先级高,富文本下文本内容的其他属性设置无效,不为空才会创建文本控件
@property (nonatomic, copy, readwrite) NSString* text;
///文本富文本,不为空才会创建文本控件
@property (nonatomic, copy, readwrite) NSAttributedString* attText;
///文本字体大小,默认系统16
@property (nonatomic, strong, readwrite) UIFont* textFont;
///文本颜色,默认系统darkTextColor
@property (nonatomic, strong, readwrite) UIColor* textColor;
///文本的背景颜色
@property (nonatomic, strong, readwrite) UIColor* textBackgroundColor;

///子文本内容,若同时设置了富文本,则富文本优先级高,富文本下文本内容的其他属性设置无效,不为空才会创建子文本控件
@property (nonatomic, copy, readwrite) NSString* subText;
///子文本富文本,不为空才会创建子文本控件
@property (nonatomic, copy, readwrite) NSAttributedString* subAttText;
///子文本字体大小,默认系统15
@property (nonatomic, strong, readwrite) UIFont* subTextFont;
///子文本颜色默认系统lightTextColor
@property (nonatomic, strong, readwrite) UIColor* subTextColor;
///子文本的背景颜色
@property (nonatomic, strong, readwrite) UIColor* subTextBackgroundColor;

#pragma mark --- 按钮属性设置,注意按钮的宽度是根据间距和父控件宽度动态计算的
///按钮的标题数组,数组个数不等于0才会创建按钮控件
@property (nonatomic, strong, readwrite) NSArray<NSString*>* btnTitlesArr;

///按钮的标题颜色,默认0x222222
@property (nonatomic, strong, readwrite) NSArray<UIColor*>* btnColorsArr;

///按钮的标题字体大小,默认系统15
@property (nonatomic, strong, readwrite) NSArray<UIFont*>* btnFontsArr;

///按钮的border宽度
@property (nonatomic, strong, readwrite) NSArray<NSNumber*>* btnBorderWidthArr;

///按钮的border颜色
@property (nonatomic, strong, readwrite) NSArray<UIColor*>* btnBorderColorArr;

///按钮的corner radius
@property (nonatomic, strong, readwrite) NSArray<NSNumber*>* btnCornerRadiusArr;

///按钮高度,默认是44
@property (nonatomic, assign, readwrite) CGFloat btnHeight;

///按钮背景颜色
@property (nonatomic, strong, readwrite) NSArray<UIColor*>* btnBackgroundColorsArr;

#pragma mark --- 间距设置
///图片和文本垂直方向的间距,默认值为20
@property (nonatomic, assign, readwrite) CGFloat marginBetweenImageAndText;

///文本和子文本垂直方向的间距,默认值为20
@property (nonatomic, assign, readwrite) CGFloat marginBetweenTextAndSubText;

///子文本和按钮垂直方向的间距,默认值为20
@property (nonatomic, assign, readwrite) CGFloat marginBetweenSubTextAndButton;

///文本距离父控件左边距,默认值为20
@property (nonatomic, assign, readwrite) CGFloat marginLeftXText;

///文本距离父控件右边距,默认值为40
@property (nonatomic, assign, readwrite) CGFloat marginRightXText;

///子文本距离父控件左边距,默认值为40
@property (nonatomic, assign, readwrite) CGFloat marginLeftXSubText;

///子文本距离父控件右边距,默认值为40
@property (nonatomic, assign, readwrite) CGFloat marginRightXSubText;

///最左边按钮距离父控件左边距,默认值为40
@property (nonatomic, assign, readwrite) CGFloat marginLeftXLeftButton;

///最右边按钮距离父控件右边距,默认值为40
@property (nonatomic, assign, readwrite) CGFloat marginRightXRightButton;

///按钮之间的间距,默认是20
@property (nonatomic, assign, readwrite) CGFloat marginBetweenButtons;

#pragma mark --- 回调设置
///是否允许触摸回调,默认是NO
@property (nonatomic, assign, getter=isAllowTouchCallback) BOOL allowTouchCallback;
///按钮回调
@property (nonatomic, copy) LQAbnormalEventBlock abnormalEventBlock;

@end

NS_ASSUME_NONNULL_END

LQAbnormalView.mファイル

//
//  LQAbnormalView.m
//  test
//
//  Created by 刘欣 on 2019/5/30.
//  Copyright © 2019 starxin. All rights reserved.
//

#import "LQAbnormalView.h"

#define kLQHexColor(c) [UIColor colorWithRed:((c>>16)&0xFF)/255.0f green:((c>>8)&0xFF)/255.0f blue:(c&0xFF)/255.0f alpha:1.0f]

@interface LQAbnormalView ()

@property (nonatomic, strong, readonly) UIImageView* iconImgView;
@property (nonatomic, strong, readonly) UILabel* textLbl;
@property (nonatomic, strong, readonly) UILabel* subTextLbl;
@property (nonatomic, strong, readonly) NSMutableArray<UIButton*>* buttonArrM;

///父控件
@property (nonatomic, weak, readonly) UIView* parentView;

@end

@implementation LQAbnormalView

#pragma mark --- life cycle
- (instancetype)init {
    if (self = [super init]) {
        [self p_initConfiguration];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self p_initConfiguration];
    }
    return self;
}
- (void)p_initConfiguration {
    _imgContentMode = UIViewContentModeScaleAspectFit;
    _imgBackgroundColor = UIColor.clearColor;
    _textFont = [UIFont systemFontOfSize:16];
    _textColor = UIColor.darkTextColor;
    _subTextFont = [UIFont systemFontOfSize:15];
    _subTextColor = UIColor.lightTextColor;
    _btnHeight = 44;
    
    _marginBetweenImageAndText = 20;
    _marginBetweenTextAndSubText = 20;
    _marginBetweenSubTextAndButton = 20;
    _marginLeftXText = 20;
    _marginRightXText = 40;
    _marginLeftXSubText = 40;
    _marginRightXSubText = 40;
    _marginLeftXLeftButton = 40;
    _marginRightXRightButton = 40;
    _marginBetweenButtons = 20;
    
    _buttonArrM = [NSMutableArray array];
    UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(p_actionForTapGesture)];
    [self addGestureRecognizer:tap];
}
- (void)willMoveToSuperview:(UIView *)newSuperview {
//    NSLog(@"newSuperview=%@", newSuperview);
    _parentView = newSuperview;
    [self p_setupView];
}
- (void)p_setupView {
    _iconImgView = UIImageView.alloc.init;
    _iconImgView.backgroundColor = _imgBackgroundColor;
    
    _textLbl = UILabel.alloc.init;
    _textLbl.numberOfLines = 0;
    _textLbl.textAlignment = NSTextAlignmentCenter;
    _textLbl.preferredMaxLayoutWidth = _parentView.frame.size.width-_marginLeftXText-_marginRightXText;
    
    _subTextLbl = UILabel.alloc.init;
    _subTextLbl.textAlignment = NSTextAlignmentCenter;
    _subTextLbl.numberOfLines = 0;
    _subTextLbl.preferredMaxLayoutWidth = _parentView.frame.size.width-_marginLeftXSubText-_marginRightXSubText;
    
    [self addSubview:self.iconImgView];
    [self addSubview:self.textLbl];
    [self addSubview:self.subTextLbl];
    
    //图片处理
    [self p_actionForInitIconImageView];
    
    //文本处理
    [self p_actionForInitTextLabel];
    
    //子文本处理
    [self p_actionForInitSubTextLabel];
    
    //按钮处理
    [self p_actionForInitButtons];
    
    //计算所有控件的有效高度
    [self p_actionForUpdateOrigin];
}

#pragma mark --- actions
///图片处理,主要是设置图片的宽高
- (void)p_actionForInitIconImageView {
    if (_imgName) {
        UIImage* img = [UIImage imageNamed:_imgName];
        if (img) {
            if (_imgWidth < 1) {
                _imgWidth = img.size.width;
            }
            if (_imgHeight < 1) {
                _imgHeight = img.size.height;
            }
            _iconImgView.frame = CGRectMake(0, 0, _imgWidth, _imgHeight);
            _iconImgView.image = img;
            _iconImgView.contentMode = _imgContentMode;
        }
    }
}
///文本处理,主要是设置文本的宽高
- (void)p_actionForInitTextLabel {
    _textLbl.backgroundColor = _textBackgroundColor;
    if (_text) {
        _textLbl.text = _text;
        _textLbl.font = _textFont;
        _textLbl.textColor = _textColor;
    }
    if (_attText) {
        _textLbl.attributedText = _attText;
    }
    [_textLbl sizeToFit];
}
///子文本处理,主要是设置子文本的宽高
- (void)p_actionForInitSubTextLabel {
    _subTextLbl.backgroundColor = _subTextBackgroundColor;
    if (_subText) {
        _subTextLbl.text = _subText;
        _subTextLbl.font = _subTextFont;
        _subTextLbl.textColor = _subTextColor;
    }
    if (_subAttText) {
        _subTextLbl.attributedText = _subAttText;
    }
    [_subTextLbl sizeToFit];
}
///按钮处理,主要是设置按钮的x和size
- (void)p_actionForInitButtons {
    if (_btnTitlesArr && _btnTitlesArr.count) {
        for (int i=0; i<_btnTitlesArr.count; i++) {
            UIButton* btn = UIButton.alloc.init;
            [btn setTitle:_btnTitlesArr[i] forState:UIControlStateNormal];
            
            if (_btnColorsArr && _btnColorsArr.count) {
                @try {
                    [btn setTitleColor:_btnColorsArr[i] forState:UIControlStateNormal];
                } @catch (NSException *exception) {
                    [btn setTitleColor:kLQHexColor(0x222222) forState:UIControlStateNormal];
                } @finally {
                    
                }
            }else {
                [btn setTitleColor:kLQHexColor(0x222222) forState:UIControlStateNormal];
            }
            
            if (_btnFontsArr && _btnFontsArr.count) {
                @try {
                    btn.titleLabel.font = _btnFontsArr[I];
                } @catch (NSException *exception) {
                    btn.titleLabel.font = [UIFont systemFontOfSize:15];
                } @finally {
                    
                }
            }else {
                btn.titleLabel.font = [UIFont systemFontOfSize:15];
            }
            
            if (_btnBorderWidthArr && _btnBorderWidthArr.count) {
                @try {
                    btn.layer.borderWidth = _btnBorderWidthArr[i].floatValue;
                } @catch (NSException *exception) {
                    btn.layer.borderWidth = 0;
                } @finally {
                    
                }
            }
            
            if (_btnBorderColorArr && _btnBorderColorArr.count) {
                @try {
                    btn.layer.borderColor = _btnBorderColorArr[i].CGColor;
                } @catch (NSException *exception) {
                } @finally {
                    
                }
            }
            
            if (_btnCornerRadiusArr && _btnCornerRadiusArr.count) {
                @try {
                    btn.layer.cornerRadius = _btnCornerRadiusArr[i].floatValue;
                } @catch (NSException *exception) {
                    btn.layer.cornerRadius = 0;
                } @finally {
                    
                }
            }
            if (_btnBackgroundColorsArr && _btnBackgroundColorsArr.count) {
                @try {
                    btn.backgroundColor = _btnBackgroundColorsArr[I];
                } @catch (NSException *exception) {
                    
                } @finally {
                    
                }
            }
            
            CGFloat width = (_parentView.frame.size.width-_marginLeftXLeftButton-_marginRightXRightButton-(_btnTitlesArr.count-1)*_marginBetweenButtons)/_btnTitlesArr.count;
            CGFloat x = _marginLeftXLeftButton+i*(width+_marginBetweenButtons);
            btn.frame = CGRectMake(x, 0, width, _btnHeight);
            btn.tag = I;
            [btn addTarget:self action:@selector(p_actionForClickButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.buttonArrM addObject:btn];
            [self addSubview:btn];
        }
    }
}
///更新控件的位置
- (void)p_actionForUpdateOrigin {
    //计算所有控件的有效高度
    CGFloat totalHeight = self.iconImgView.frame.size.height+self.textLbl.frame.size.height+self.subTextLbl.frame.size.height+self.buttonArrM.firstObject.frame.size.height+self.marginBetweenImageAndText+self.marginBetweenTextAndSubText+self.marginBetweenSubTextAndButton;
    
    //计算控件的位置
    CGFloat originalY = (self.parentView.frame.size.height-totalHeight)*0.5;
    
    CGRect frame = self.iconImgView.frame;
    CGFloat x = (self.parentView.frame.size.width-self.imgWidth)*0.5;
    CGFloat y = originalY;
    self.iconImgView.frame = CGRectMake(x, originalY, self.imgWidth, self.imgHeight);
    
    frame = self.textLbl.frame;
    x = (self.parentView.frame.size.width-frame.size.width)*0.5;
    y = CGRectGetMaxY(self.iconImgView.frame)+self.marginBetweenImageAndText;
    self.textLbl.frame = CGRectMake(x, y, frame.size.width, frame.size.height);
    
    frame = self.subTextLbl.frame;
    x = (self.parentView.frame.size.width-frame.size.width)*0.5;
    y = CGRectGetMaxY(self.textLbl.frame)+self.marginBetweenTextAndSubText;
    self.subTextLbl.frame = CGRectMake(x, y, frame.size.width, frame.size.height);
    
    __weak typeof(self) weakSelf = self;
    [self.buttonArrM enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        CGRect frame = obj.frame;
        CGFloat y = CGRectGetMaxY(weakSelf.subTextLbl.frame)+weakSelf.marginBetweenSubTextAndButton;
        obj.frame = CGRectMake(frame.origin.x, y, frame.size.width, frame.size.height);
    }];
    
    //计算异常界面的实际尺寸和位置
    self.frame = self.parentView.bounds;
}
///点击按钮回调
- (void)p_actionForClickButton:(UIButton *)sender {
    if (self.abnormalEventBlock) {
        self.abnormalEventBlock(sender.tag);
    }
}
- (void)p_actionForTapGesture {
    if (self.isAllowTouchCallback) {
        if (self.abnormalEventBlock) {
            self.abnormalEventBlock(-1);
        }
    }
}

- (void)dealloc {
    NSLog(@"dealloc --- %@", NSStringFromClass(self.class));
}

@end

コールの例

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
    [self.view addSubview:self.tableView];
    
    self.tableView.sx_networkDelegate = self;
    self.tableView.sx_configDelegate = self;
    [self.tableView sx_initRequestData];
    
    LQAbnormalView* abnormalView = [[LQAbnormalView alloc] init];
    abnormalView.imgName = @"语音按键";
    abnormalView.imgBackgroundColor = UIColor.lightGrayColor;
    
    NSString* text = @"对不起,你无权查看此文件,请联系你的直接上司修改权限";
    abnormalView.text = text;
//    abnormalView.attText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15], NSForegroundColorAttributeName:UIColor.purpleColor}];
    abnormalView.textFont = [UIFont systemFontOfSize:13];
    abnormalView.textColor = UIColor.purpleColor;
    abnormalView.textBackgroundColor = UIColor.lightGrayColor;
    
    NSString* subtext = @"我就是不给你看,你能咋地,来打我呀,我怕你呀";
    abnormalView.subText = subtext;
    abnormalView.subTextFont = [UIFont systemFontOfSize:13];
    abnormalView.subTextColor = UIColor.redColor;
    abnormalView.subTextBackgroundColor = UIColor.lightGrayColor;
    
    abnormalView.btnTitlesArr = @[@"取消", @"确定"];
    abnormalView.btnColorsArr = @[UIColor.redColor];
    abnormalView.btnFontsArr  = @[[UIFont systemFontOfSize:20],[UIFont systemFontOfSize:16],[UIFont systemFontOfSize:16]];
    abnormalView.btnBorderWidthArr = @[@0.5];
    abnormalView.btnBorderColorArr = @[UIColor.lightGrayColor,UIColor.redColor];
    abnormalView.btnCornerRadiusArr = @[@2];
    abnormalView.btnHeight = 60;
    abnormalView.btnBackgroundColorsArr = @[UIColor.purpleColor];
    
    abnormalView.marginBetweenImageAndText = 10;
    abnormalView.marginBetweenTextAndSubText = 20;
    abnormalView.marginBetweenSubTextAndButton = 10;
    
    abnormalView.marginLeftXText = 100;
    abnormalView.marginRightXText = 60;
    abnormalView.marginLeftXSubText = 80;
    abnormalView.marginRightXSubText = 100;
    abnormalView.marginLeftXLeftButton = 100;
    abnormalView.marginRightXRightButton = 50;
    abnormalView.marginBetweenButtons = 5;
    
    abnormalView.allowTouchCallback = YES;
    abnormalView.abnormalEventBlock = ^(NSInteger idx) {
        NSLog(@"idx = %zd", idx);
    };
    
    [self.view addSubview:abnormalView];
}

実際の結果は、

11379923-1f1be8ae6892901b.png
image.png

ます。https://www.jianshu.com/p/9e2cacc44cdfで再現

おすすめ

転載: blog.csdn.net/weixin_34326558/article/details/91333156