IOS开发UI基础之综合应用

一 懒加载

  • 作用:
    • 用到时再加载
    • 保证数据只会被加载一次
  • 好处:
    • 节约内存空间
@interface ViewController ()
@property (nonatomic, strong)NSArray *shops;
@end

@implementation ViewController
// 重写getter方法
- (NSArray *)shops
{
    if (_shops == nil) {
        NSLog(@"创建一个新的数组");
        _shops = @[
                       @{@"name":@"单肩包",
                         @"icon":@"danjianbao"},
                       @{@"name":@"链条包",
                         @"icon":@"liantiaobao"},
                       @{@"name":@"钱包",
                         @"icon":@"qianbao"},
                       @{@"name":@"手提包",
                         @"icon":@"shoutibao"}
                       ];
    }
    return _shops;
}
@end

二 plist文件

  • plist文件作用:

    • 将数据和逻辑分离
    • 提高了代码的扩展性
  • 获取plist文件的绝对路径

NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:@"shops" ofType:@"plist"];

//  根据路径加载plist文件
_shop = [NSArray arrayWithContentOfFile:path];

注意点: 文件名称中不能包含info单词

三 字典转模型

  • 字典的弊端

    • 1.字典的key是一个字符串, 写错不会报错
    • 2.英语不好, 单词记不住
    • 3.由于key是一个字符串, 所以在编码的时候没有提示, 编码效率比较低
  • 模型的优点

    • 可以通过属性来获取值, 属性写错会报错
    • 不用去记单词, 只需要记住以什么开头即可
    • 由于属性有提示, 所以编码效率比较高
  • 注意:

    • 字典转模型的操作应该封装到模型中
    • 如果不封装在模型中的弊端:
      • 如果有很多地方都需要字典转模型, 那么很多地方都需要写重复的代码
      • 需求变更所有字典转模型的地方都需要修改
+ (instancetype)shopWithDict:(NSDictionary *)dict
{
    NJShop *shop = [[self alloc] init];
    shop.name = dict[@"name"];
    shop.icon = dict[@"icon"];
    return shop;
}
  • 规律:

    • 在开发中但凡看到字典,一般情况下都会创建一个与之对应的模型来保存字典中的数据
  • 模型的类名命名注意:

    • 一般情况下在自定义一个类的时候会给每个类添加一个”类前缀”, 这样可以避免多人开发发生冲突

四 自定义view

  • 自定义View
  • 目的:

    • 提高代码的复用性
    • 屏蔽内部的实现细节
  • 步骤:

    • 1.自定义一个类继承于UIView
    • 2.在initWithFrame方法中添加子控件
    • 3.在layoutSubviews中设置子控件的位置
    • 4.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据
  • 类工厂方法(便利构造器)

    • 按照苹果的风格和规范, 一般情况一个用于创建对象的对象方法会对应一个类方法
    • 可以通过类工厂方法, 快速的根据数据创建一个对象
  • 注意点:

    • 返回值一定要使用instancetype, 不要使用id
    • 在类工厂方法中创建对象, 使用self, 不要使用类名
  • layoutSubviews

  • 作用:
    • 布局子控件, 用于调整子控件的位置
- (void)layoutSubviews
{
    [super layoutSubviews];

    CGFloat shopViewWidth = self.frame.size.width;
    CGFloat shopViewHeight = self.frame.size.height;
    // 1.布局图片的位置
     self.iv.frame = CGRectMake(0, 0, shopViewWidth, shopViewWidth);
    // 2.布局文本的位置
    self.lable.frame = CGRectMake(0, shopViewWidth, shopViewWidth, shopViewHeight - self.iv.frame.size.height);
}
  • 什么时候调用

    • 控件第一次被创建
    • 控件的尺寸(size)被修改会调用
    • 修改位置不会调用
  • 注意点:

    • 重写layoutSubviews方法, 一定要调用父类的方法([super layoutSubviews])
  • 重写set方法,设置子控件数据

- (void)setShop:(NJShop *)shop
{
    _shop = shop;
    // 设置子控件的数据
    self.iv.image = [UIImage imageNamed:_shop.icon];
    self.lable.text = _shop.name;
}

五 新增快速创建方法

  • 重写initWithFrame
//   init方法内部会调用initWithFrame
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {

        // 1.创建一张图片
        UIImageView *iv = [[UIImageView alloc] init];
        iv.backgroundColor = [UIColor yellowColor];
        [self addSubview:iv];
        self.iv = iv;

        // 2.创建一个文本
        UILabel *lable = [[UILabel alloc] init];
        lable.backgroundColor = [UIColor purpleColor];
        lable.textAlignment = NSTextAlignmentCenter;
        [self addSubview:lable];
        self.lable = lable;
    }
    return self;
}

注意: 一般情况下自定义一个控件会重写控件的initWithFrame方法, , 因为用户可能通过init方法创建也可能通过initWithFrame方法创建, 为了保证无论用户通过哪一个方法创建都能添加子控件, 所以重写initWithFrame

  • 创建商品,模仿苹果方法
  NJShopView *shopView = [NJShopView shopViewWithShop: self.shops[index]];
//    NJShopView *shopView = [[NJShopView alloc] initWithShop:self.shops[index]];

   shopView.backgroundColor = [UIColor redColor];
   shopView.frame = CGRectMake(shopX, shopY, 70, 100);
   [self.shopsView addSubview:shopView];
  • 一个便利构造器对应一个类工厂方法
// 注意:自定义构造方法中的WithW一定要大写
- (instancetype)initWithShop:(NJShop *)shop;

+ (instancetype)shopViewWithShop:(NJShop *)shop;
- (instancetype)initWithShop:(NJShop *)shop
{
    if (self = [super init]) {
        self.shop = shop;
    }
    return self;
}

+ (instancetype)shopViewWithShop:(NJShop *)shop
{
 // 注意: 如果在类方法中创建对象, 建议使用self, 不要使用类名 
    return [[self alloc] initWithShop:shop];
 }

六 Xib

  • 什么是Xib

    • Xib和Storyboard一样都是用来描述界面的
    • Xib是Storyboard的前身
  • Xib和storyboard对比

    • 共同点:

      • 都用来描述软件界面
      • 都用Interface Builder工具来编辑
      • 本质都是转换成代码去创建控件
    • 不同点

      • Xib是轻量级的,用来描述局部的UI界面
      • Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系
  • 如何加载xib

    • 第一种方式
    NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil]
    • 第二种方式
    // 注意: 创建UINib对象时需要传入一个bundle, 如果是去mainBundle中查找, 那么可以直接传一个nil
    UINib *nib = [UINib nibWithNibName:@"xib文件名" bundle:nil];
    NSArray *views = [nib instantiateWithOwner:nil options:nil];
    
  • 规律

    • 一般情况下苹果的方法中要求传入一个bundle参数, 直接传nil就代表mainBundle

七 通过Xib自定义View

  • 步骤
    • 1.新建一个Xib描述界面
    • 2.新建一个继承于Xib界面中父控件类型的类来管理界面
    • 3.在xib中关联界面和类
    • 4.重写awakeFromNib方法, 进行一些初始化
    • 5.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据
  • 代码示例:
// 1.加载XIB
  XMGShopView *shopView = [[[NSBundle mainBundle] loadNibNamed:@"XMGShopView" owner:nil options:nil] firstObject];
// 2.设置frame
   CGRect tempFrame = shopView.frame;
   tempFrame.origin.x = shopX;
   tempFrame.origin.y = shopY;
   shopView.frame = tempFrame;
// 3.设置数据
    NJShop *shop = self.shops[index];
    shopView.iconView.image = [UIImage imageNamed:shop.icon];
    shopView.nameLabel.text = shop.name;
//  添加子控件
   [self.shopsView addSubview:shopView];
  • 注意点:不应该在控制器中加载xib, 应该将加载xib的操作封装到自定义view中
+ (instancetype)shopView
{
    return [[[NSBundle mainBundle] loadNibNamed:@"XMGShopView" owner:nil options:nil] firstObject];
}
  • 方法的执行顺序
    • 如果是通过xib或者Storyboard创建一个控件, 不会调用initWithFrame方法
    • 在”创建时”会调用initWithCoder方法
      • 控件不一定被创建好了
    • 在”创建后”会调用awakeFromNib
      • 控件一定被创建好了

八 Xib原理

  • 1>根据custom class创建对象
 XMGShopView *shopView = [XMGShopView alloc] init];    
  • 2>根据xib中的设置, 设置控件的相关属性
  shopView.backgroundColor = [UIColor redColor];
  shopView.frame = CGRectMake(0, 0, 70, 100);
  • 3>创建所有子控件, 并且设置子控件的属性
  UIImageView *iv = [[UIImageView alloc] init];
  iv.frame = CGRectMake(0, 0, 70, 70);
  UILabel *label = [[UILabel alloc] init];
  label.frame = CGRectMake(0, 70, 70, 30);
  • 4>检查子控件是否有连线, 如果有就进行关联
    self.iconView = iv;
    self.nameLabel = label;
  • 5>将所有子控件添加到父控件中
     [shopView addSubview:iv];
     [shopView addSubview:label];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值