阅读 258

iOS中自定义view的封装(iOS中自定义导航栏)

自定义view的封装

  • 如果一个 view 内部的子控件比较多,一般会考虑自定义一个 view,把它内部的子控件创建并封装起来,不让外界看见

  • 外界可以传入对应的数据模型给 viewview 拿到模型数据后,给内部子控件设置对应的数据


代码封装自定义view

  • 代码封装自定义 view 的步骤

    1. 新建一个继承 UIView 的类

    2. initWithFrame: 方法中添加子控件(也可以使用懒加载)

    3. 重写模型属性 set 方法,在 set 方法中设置模型属性到子控件上

    4. layoutSubviews 方法中设置子控件的 frame(一定要调用 [super layoutSubviews]

  • 关于 layoutSubviews 在以下情况下会被调用

    • init 初始化不会触发 layoutSubviews

    • addSubview 会触发 layoutSubviews

    • 设置 viewFrame 会触发 layoutSubviews,当然前提是 frame 的值设置前后发生了变化

    • 滚动一个 UIScrollView 会触发 layoutSubviews

    • 旋转 Screen 会触发父 UIView 上的 layoutSubviews 事件

    • 改变一个 UIView 大小的时候也会触发父 UIView 上的 layoutSubviews 事件

示例

@class ImageData; @interface ImageDataView : UIView //设置模型属性 @property (nonatomic,strong) ImageData *imageData; @end 复制代码

#import "ImageData.h" @interface ImageDataView() @property (nonatomic,strong) UIImageView *imageView; @property (nonatomic,strong) UILabel *label; @end @implementation ImageDataView - (instancetype)initWithFrame:(CGRect)frame{     if (self = [super initWithFrame:frame]) {          }     return self; } #pragma mark- 懒加载 - (UIImageView *)imageView{     if (_imageView == nil) {         UIImageView *imageView = [[UIImageView alloc]init];         [imageView setBackgroundColor:[UIColor blueColor]];         [self addSubview:imageView];         _imageView = imageView;     }     return _imageView; } - (UILabel *)label{     if (_label == nil) {         UILabel *label = [[UILabel alloc]init];         [label setBackgroundColor:[UIColor redColor]];         label.textAlignment = NSTextAlignmentCenter;         [self addSubview:label];         _label = label;     }     return _label; } #pragma mark- 模型赋值 - (void)setImageData:(ImageData *)imageData{     _imageData = imageData;     self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",imageData.icon]];     self.label.text = imageData.name; } #pragma mark- 子控件坐标 //这个方法专门用于布局子控件,一般在这里设置子控件的frame //当控件本身的尺寸发送改变时,系统会自动调用这个方法 - (void)layoutSubviews{     [super layoutSubviews];          CGFloat personW = self.frame.size.width;     CGFloat personH = self.frame.size.height;          self.imageView.frame = CGRectMake(0, 0, personW, personH-20);     self.label.frame = CGRectMake(0, personH-20, personW, 20); } @end 复制代码

方法调用

ImageData *imageData = [[ImageData alloc]initWithDic:dic]; ImageDataView *view = [[ImageDataView alloc]init]; view.imageData = imageData; view.frame = CGRectMake(shopX, shopY, imageW, imageH); [bgView addSubview:view]; 复制代码


xib封装自定义view

  1. 新建一个继承 UIView 的类

  2. 新建一个xib文件(xib的文件名最好和控件名一样,修改最外面那个控件的 class 为控件类名 )

    11975486-154d5a2a195c6dfe-2.png

  3. 添加子控件、设置子控件属性 11975486-4dde8f0084d56ec1.png

  4. 加载 xib 文件

    [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] lastObject] 复制代码

  5. 重写模型属性 set 方法,在 set 方法中设置模型属性到子控件上

示例

#import "ImageDataView.h" #import "ImageData.h" @interface ImageDataView() @property (weak, nonatomic) IBOutlet UIImageView *imageView; @property (weak, nonatomic) IBOutlet UILabel *label; @end @implementation ImageDataView + (instancetype)shareImageDataView{     return [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] lastObject]; } #pragma mark- 模型赋值 - (void)setImageData:(ImageData *)imageData{     _imageData = imageData;     self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",imageData.icon]];     self.label.text = imageData.name; } @end 复制代码


两种方法封装自定义view的比较

  • 在调整子控件的 frame 时,使用纯代码比 xib 更灵活,子控件可以在 layoutSubviews 方法中灵活调整自己的 frame。而用 xib 相对于比较死板,但是更简单,更方便

  • 自定义 view 时,如果该 view 一直一个样式,推荐使用xib,简单方便

  • 而子控件经常随着父控件变化而变化,推荐使用纯代码,灵活多变

 伪原创工具 SEO网站优化  https://www.237it.com/ 

作者:NewBoy
链接:https://juejin.cn/post/7034859790341931021

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐