iOS-简单两步搞定自定义View

目录

  • 前言
  • 【一】纯代码自定义View
    ---- 基本用法
    ---- 使用构造方法传入外部数据
  • 【二】XIB自定义View
    ---- 基本用法
    ---- 模拟简单弹框VIew使用案例

前言

相信大家对于自定义View并不陌生,很多业务上面都会遇到,今天做了个总结,三步骤搞定自定义VIew,分类纯代码和Xib布局的方式。

【一】纯代码自定义View

基本用法

  • 新建OC文件MyCodeCustomView.hMyCodeCustomView.m
  • initWithFrame:方法中将子控件添加到View中。
  • layoutSubviews设置内部控件的frame
  • 添加相关逻辑方法,在控制器中进行调用。

MyCodeCustomView.h中:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyCodeCustomView : UIView

// 显示View
- (void)showPopView;

// 隐藏View
- (void)dismissPopView;

// Block点击事件回调处理
@property (copy,nonatomic) void (^submitBtnClickBlock)(UIView * view, NSString * keyStr);

@end

NS_ASSUME_NONNULL_END

MyCodeCustomView.m中:

#import "MyCodeCustomView.h"

@interface MyCodeCustomView ()
@property (nonatomic, weak) UILabel *nameLab;
@property (nonatomic, weak) UIImageView *headImgVIew;
@property (nonatomic, weak) UIButton *submitBtn;
@end

@implementation MyCodeCustomView

#pragma mark - 原始初始化方法

// 1、首先调用init方法
- (instancetype)init{
    if (self = [super init]) {
        [self setUp];
    }
    return self;
}
  
// 2、然后调用initWithFrame方法
- (instancetype)initWithFrame:(CGRect)frame{
    if (self =[super initWithFrame:frame]) {
        [self setUp];
    }
    return self;
}

#pragma mark - UI布局

// 初始化UI控件
- (void)setUp{
 
    UILabel *nameLab = [[UILabel alloc] init];
    nameLab.backgroundColor = [UIColor yellowColor];
    nameLab.textAlignment = NSTextAlignmentCenter;
    [self addSubview:nameLab];
    _nameLab = nameLab;
    
    UIImageView *headImgVIew = [[UIImageView alloc] init];
    headImgVIew.backgroundColor = [UIColor redColor];
    [self addSubview:headImgVIew];
    _headImgVIew = headImgVIew;
    
    UIButton *submitBtn = [[UIButton alloc] init];
    submitBtn.backgroundColor = [UIColor blueColor];
    [submitBtn addTarget:self action:@selector(submitAction) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:submitBtn];
    _submitBtn = submitBtn;
 
}

// 设置UI控件的frame
- (void)layoutSubviews{
    [super layoutSubviews];
    // 1.获取当前控件的尺寸
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    // 2.设置子控件的frame
    self.nameLab.frame = CGRectMake(0, 0, width, 50);
    self.headImgVIew.frame = CGRectMake(0, 50, 100, 100);
    self.submitBtn.frame = CGRectMake(0, 150, width, height-450);
}

// 点击事件处理
- (void)submitAction {
    // 根据自己业务处理TODO
    NSLog(@"hello world !");
    [self dismissPopView]; 
    // Block点击事件回调处理
    if (self.submitBtnClickBlock) {
        self.submitBtnClickBlock(self, @"hello world");
    }
}

#pragma mark - 视图显示/隐藏控制

// 显示View
- (void)showPopView{
    [[[UIApplication sharedApplication] windows].firstObject addSubview:self];
}

// 隐藏View
- (void)dismissPopView{
    [self removeFromSuperview];
}

@end

MainViewCtl.h中:

#import "MainViewCtl.h"
#import "MyCodeCustomView.h"

@interface MainViewCtl ()
@property (strong,nonatomic) MyCodeCustomView * codeCustomView;
@end

@implementation MainViewCtl

- (void)viewDidLoad {
    [super viewDidLoad];
    // 在合适的时候先显示View
    [self.codeCustomView showPopView];
    // 在合适的时候先隐藏View
    [self.codeCustomView dismissPopView];
    
}

#pragma mark - 懒加载
 
- (MyCodeCustomView *)codeCustomView{
    if (!_codeCustomView) {
        _codeCustomView =  [[MyCodeCustomView alloc] initWithFrame:CGRectMake(0, 0, 300, 500)];
        _codeCustomView.frame =  CGRectMake(0, 0, 300, 500);
        // View点击方法回调处理
        _codeCustomView.submitBtnClickBlock = ^(UIView * _Nonnull view, NSString * _Nonnull keyStr) {
            // TODO
        };
    }
    return _codeCustomView;
}
@end

使用构造方法传入外部数据

MyCodeCustomView.h中增加:

// 构造方法 
- (instancetype)initWithData:(NSDictionary *)dataDict;

// 外部数据
@property (nonatomic,strong) NSDictionary *dataDict;

MyCodeCustomView.m中增加:

#pragma mark - 自定义初始化方法

// 对象方法
- (instancetype)initWithData:(NSDictionary *)dataDict{
    if (self = [super init]) {
        // 注意:先创建后赋值
        [self setUp];
        self.dataDict = dataDict;
    }
    return self;
}

#pragma mark - 数据相关

// 数据Setter方法,外部传入数据就会调用该方法
- (void)setDataDict:(NSDictionary *)dataDict{
    _dataDict = dataDict;
    self.nameLab.text = dataDict[@"realName"];
}

MyCodeCustomView.h中:

 
@implementation MainViewCtl

- (void)viewDidLoad {
    [super viewDidLoad];
    // 在合适的时候先显示View
    [self.codeCustomView showPopView];
    // 在合适的时候先隐藏View
    [self.codeCustomView dismissPopView];
    // 在合适的时候调整数据
    self.codeCustomView.dataDict = @{@"realName":@"李四"}; 
}

#pragma mark - 懒加载
 
- (MyCodeCustomView *)codeCustomView{
    if (!_codeCustomView) {
        _codeCustomView =  [[MyCodeCustomView alloc] initWithData:@{@"realName":@"张三"}];
        _codeCustomView.frame =  CGRectMake(0, 0, 300, 500);
        // View点击方法回调处理
        _codeCustomView.submitBtnClickBlock = ^(UIView * _Nonnull view, NSString * _Nonnull keyStr) {
            // TODO
        };
    }
    return _codeCustomView;
}  
@end

【二】XIB自定义View

基本用法

  • 新建OC文件MyCustomView.hMyCustomView.m,新建XIB文件MyCustomView.xib
  • 在XIB文件中进行UI布局。
  • 在Xib的Class中设置类名。
  • 在XIB中我们添加控件,进行布局约束了,所以只需要关注 awakeFromNib方法即可。
  • 使用XIB方式,在初始化的时候我们需要返回给到XIB对象。

用法一:

我们需要在自定义View中做操作,需要实例化对象,然后进行逻辑操作。

MyCustomView.h中:

@interface MyCustomView : UIView

// XIB初始化方法
+ (instancetype)initWithCustomView;

// 显示View
- (void)showPopView;

// 隐藏View
- (void)dismissPopView;

// Block点击事件回调处理
@property (copy,nonatomic) void (^submitBtnClickBlock)(UIView * view, NSString * keyStr);

@end

MyCustomView.m中:

#import "MyCustomView.h"

@interface MyCustomView ()
@property (weak, nonatomic) IBOutlet UIView * infoView;
@property (weak, nonatomic) IBOutlet UIButton *checkBtn;
@property (weak, nonatomic) IBOutlet UIButton *submitBtn;
@property (copy, nonatomic) NSString *keyStr;
@end

@implementation MyCustomView

#pragma mark - 初始化

// XIB初始化方法
+ (instancetype)initWithCustomView{
    return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] lastObject];
}

// Xib初始化完毕第一个调用的方法
- (void)awakeFromNib{
    [super awakeFromNib];
    [self initBaseConfig];
}

// 在这里写初始化的一些功能和设置
- (void)initBaseConfig {
    
}

#pragma mark - 视图显示/隐藏控制

// 显示View
- (void)showPopView{ 
    [[[UIApplication sharedApplication] windows].firstObject addSubview:self];
}

// 隐藏View
- (void)dismissPopView{
    [self removeFromSuperview];
}

#pragma mark - 点击事件处理

- (IBAction)btnClickAction:(UIButton *)sender {
   
   if (sender == self.checkBtn) {
       
   }else if (sender == self.submitBtn) {
       // Block点击事件回调处理
       if (self.submitBtnClickBlock) {
           self.submitBtnClickBlock(self, @"hello world");
       }
   }
  
}
@end

在控制器MainViewCtl.m中:

#import "MainViewCtl.h"
#import "MyCustomView.h"

@interface MainViewCtl ()
@property (strong,nonatomic) MyCustomView * customView;
@end

@implementation MainViewCtl

- (void)viewDidLoad {
    [super viewDidLoad];
    // 在合适的时候先显示View
    [self.customView showPopView];
    // 在合适的时候先隐藏View
    [self.customView dismissPopView];
}

#pragma mark - 懒加载

- (MyCustomView *)customView{
    if (!_customView) {
        _customView = [MyCustomView initWithCustomView];
        _customView.frame =  CGRectMake(0, 0, 300, 500);
        // View点击方法回调处理
        _customView.submitBtnClickBlock = ^(UIView * _Nonnull view, NSString * _Nonnull keyStr) {
            // TODO
        };
    }
    return _customView;
}
@end

模拟简单弹框VIew使用案例

例如一个弹框功能,我们无需再控制器进行操作,逻辑全部在View中处理。
使用类方法进行初始化即可。

MyCustomView.h中:

 
@interface MyCustomView : UIView

// XIB初始化方法
+ (instancetype)initWithCustomView;

// 带参数的类构造方法
+ (void)initWithCustomViewWithKey:(NSString *)keyStr;

// 显示View
- (void)showPopView;

// 隐藏View
- (void)dismissPopView;

// Block点击事件回调处理
@property (copy,nonatomic) void (^submitBtnClickBlock)(UIView * view, NSString * keyStr);

@end

MyCustomView.m中:

#import "MyCustomView.h"

@interface MyCustomView ()
@property (weak, nonatomic) IBOutlet UIView * infoView;
@property (weak, nonatomic) IBOutlet UIButton *checkBtn;
@property (weak, nonatomic) IBOutlet UIButton *submitBtn;
@property (copy, nonatomic) NSString *keyStr;
@end

@implementation MyCustomView

#pragma mark - 初始化

// XIB初始化方法
+ (instancetype)initWithCustomView{
    return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] lastObject];
}

// 带参数的构造方法
+ (void)initWithCustomViewWithKey:(NSString *)keyStr{
    MyCustomView *customView = [MyCustomView initWithCustomView];
    customView.keyStr = keyStr;
}

// Xib初始化完毕第一个调用的方法
- (void)awakeFromNib{
    [super awakeFromNib];
    [self initBaseConfig];
}

// 在这里写初始化的一些功能和设置
- (void)initBaseConfig {
    // 直接展示View
    self.frame = CGRectMake(0, 0, 300, 300);
    [self showPopView];
    if ([_keyStr isEqualToString:@"YES"]) {
        // TODO
    }
}

#pragma mark - 视图显示/隐藏控制

// 显示View
- (void)showPopView{ 
    [[[UIApplication sharedApplication] windows].firstObject addSubview:self];
}

// 隐藏View
- (void)dismissPopView{
    [self removeFromSuperview];
}

#pragma mark - 点击事件处理

- (IBAction)btnClickAction:(UIButton *)sender {
   // 只在CustomView里面完成逻辑处理,和外界不做交互
    [self dismissPopView];
   if (sender == self.checkBtn) {
       self.checkBtn.selected = !self.checkBtn.isSelected;
   }else if (sender == self.submitBtn) {
       [NSUserDefaults setValue:@"hello world" forKey:@"MYKEY"];
   }
}

@end

在控制器MainViewCtl.m中:

#import "MainViewCtl.h"
#import "MyCustomView.h"

@interface MainViewCtl ()
@end

@implementation MainViewCtl

- (void)viewDidLoad {
    [super viewDidLoad];
    // 仅做展示,逻辑操作在内部进行
    [MyCustomView initWithCustomViewWithKey:@"YES"];
}
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容