IOS基础UI之(六)综合小案例-应用管理

 实现效果:

       (1)已九宫格的形式展现应用信息

       (2)点击下载按钮后,提示下载完成提醒

                                                                                 

 

 掌握知识点:

        (1)UIView常见属性和方法

        (2)九宫格的实现

        (3)字段转模型

        (4)xib的使用

        (5)自定义view,封装view

        (6)mvc的思想



 九宫格实现分析:

  特点:列号决定x值(每一列的x值一样),行号决定y值(每一行的y值一样)

     

    //总列数
    int totalCount = 3;
    //每个格子的尺寸
    CGFloat appW = 85;
    CGFloat appH = 100;
    //间隙 = (控制器view宽度 - 3*应用宽度)/4;
    CGFloat marginX = (self.view.frame.size.width - totalCount * appW)/(totalCount+1);
    CGFloat marginY = 20;
    
    for(int i = 0;i<self.apps.count;i++){
        //添加一个小框框
        UIView *appView = [[UIView alloc] init];
        //添加背景色
        //appView.backgroundColor = [UIColor greenColor];
        //计算行号和列好
        int row = i/totalCount;
        int col = i%totalCount;
        //计算位置
        CGFloat appX = marginX + col*( appW + marginX) ;
        CGFloat appY = 30 + row * ( appH + marginY);
        appView.frame = CGRectMake(appX, appY, appW, appH);
        //添加到控制器中
        [self.view addSubview:appView];
        
    }


字典转模型:

使用字典的坏处:

   一般情况下,设置数据和取出数据都使用字符串类型的key”,编写这些key时,编译器不会有任何友善提示,需要手敲

  dict[@"name"] =@"Jack";

  NSString *name = dict[@"name"];

   手敲字符串keykey容易写错。Key如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据


使用模型的好处:

  所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业

  模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性

  使用模型访问属性时,编译器会提供一系列的提示,提高编码效率

  app.name = @"Jack”;

  NSString *name = app.name;


使用模型注意点:

  为了降低耦合性,字典转模型的过程最好封装在模型内部

     为了别人跟容易调用自己的模型,最好规范自己提供的构造方法命名:      

   - (instancetype)initWithDict:(NSDictionary *)dict;

   + (instancetype)xxxWithDict:(NSDictionary *)dict;


应用信息模型:

ZXHApp.h

//
//  ZXHApp.h


#import <Foundation/Foundation.h>

@interface ZXHApp : NSObject

//应用名称
@property(nonatomic,copy) NSString *name;
//图标
@property(nonatomic,copy) NSString *icon;


/**
 *  字典初始化模型
 *
 *  @param dict 字典
 *
 *  @return 模型
 */
-(instancetype)initWithDict:(NSDictionary *)dict;

/**
 *  字典初始化模型(类方法)
 *
 *  @param dict 字典
 *
 *  @return 模型
 */
+(instancetype)appWithDict:(NSDictionary *)dict;
 
@end


ZXHApp.m
//
//  ZXHApp.m


#import "ZXHApp.h"

@implementation ZXHApp

/**
 *  字典初始化模型
 *
 *  @param dict 字典
 *
 *  @return 模型
 */
-(instancetype)initWithDict:(NSDictionary *)dict{
    if (self = [super init]) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

/**
 *  字典初始化模型
 *
 *  @param dict 字典(类方法)
 *
 *  @return 模型
 */
+(instancetype)appWithDict:(NSDictionary *)dict{
    //return [[ZXHApp alloc]initWithDict:dict];
    //建议使用这种方式,self:谁调此方法self就指向谁。 这样的好处是,子类继承后,调用此方法就指向子类
    return [[self alloc]initWithDict:dict];
    
    
}
@end



xib的使用和自定义view

Xib和storyboard对比:

    共同点:

       都用来描述软件界面

       都用Interface Builder工具来编辑

  不同点:

   Xib是轻量级的,用来描述局部的UI界面

   Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系


Xib文件的使用:

       Xib 文件可 以用来描述某一块局部的 UI 界面

      Xib文件的加载:

     方法1

      NSArray *objs = [[NSBundlemainBundle] loadNibNamed:@"ZXHAppView"owner:nil options:nil];

             这个方法会创建xib中的所有对象,并且将对象按顺序放到objs数组中

           (如果xib如右图所示,那么objs数组中依次会有3个对象:1UIView1UIButton1UISwitch

   方法2

      bundle参数可以为nil,默认就是main bundle

      UINib *nib = [UINibnibWithNibName:@"ZXHAppView"bundle:[NSBundlemainBundle]];

      NSArray *objs = [nibinstantiateWithOwner:niloptions:nil];

在开发阶段,面向开发者的是xib文件;当把应用装到手机上时,xib文件就会转为nib文件


xib结合自定义view的使用步骤:

1> 新建一个继承UIView的自定义view,假设类名叫做(ZXHAppView)

2> 新建一个ZXHAppView.xib文件来描述ZXHAppView内部的结构

3> 修改UIView的类型为ZXHAppView真实类型

4>将内部的子控件跟ZXHAppView进行属性连线

5> ZXHAppView提供一个模型属性

6>重写模型属性的set方法,因为在set方法中可以拿到外界传递的模型数据

7>把模型数据拆开,分别设置数据到对应的子控件中

8>补充:提供一个创建ZXHAppView的类方法,将读取xib文件的代码屏蔽起来


自定义view,获取模型数据并将内部的子控件跟ZXHAppView进行属性连线

ZXHAppView.h

//
//  ZXHAppView.h


#import <UIKit/UIKit.h>
@class ZXHApp;

@interface ZXHAppView : UIView

//数据模型
@property(nonatomic,strong) ZXHApp  *app;

/**
 *  通过模型数据来创建一个view
 *
 *  @return
 */
+(instancetype)appView;

/**
 *  通过模型数据来创建一个view
 *
 *  @return
 */
+(instancetype)appViewWithApp:app;
@end

ZXHAppView.m

//
//  ZXHAppView.m


#import "ZXHAppView.h"
#import "ZXHApp.h"

@interface ZXHAppView()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
- (IBAction)download:(UIButton *)sender;

@end

@implementation ZXHAppView

/**
 *  通过模型数据来创建一个view
 *
 *  @param app ZXHApp
 *
 *  @return ZXHAppView
 */
+(instancetype)appViewWithApp:(id)app{
    //获取xib文件
    NSBundle *bundle = [NSBundle mainBundle];
    NSArray *objs = [bundle loadNibNamed:@"ZXHAppView" owner:nil options:nil];
    ZXHAppView *appView = [objs lastObject];
    appView.app = app;
    
    return appView;
}

/**
 *  通过模型数据来创建一个view
 *
 *  @return ZXHAppView
 */
+(instancetype)appView{
    return [self appViewWithApp:nil];
}

/**
 *  重写set方法
 *
 *  @param app ZXHApp对象
 */
-(void)setApp:(ZXHApp *)app{
    
    _app = app;
    //设置图片
    self.imageView.image = [UIImage imageNamed:app.icon];
    //设置名称
    self.nameLabel.text = app.name;
    
}
    
}
@end



xib修改UIView的类型为ZXHAppView真实类型





修改九宫格的实现代码:

//
//  ViewController.m
//  九宫格


#import "ViewController.h"
#import "ZXHApp.h"
#import "ZXHAppView.h"

@interface ViewController ()
/** 存放应用信息 */
@property(nonatomic,strong) NSArray *apps;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    //添加应用信息
    
    //总列数
    int totalCount = 3;
    //应用尺寸
    CGFloat appW = 85;
    CGFloat appH = 100;
    //间隙 = (控制器view宽度 - 3*应用宽度)/4;
    CGFloat marginX = (self.view.frame.size.width - totalCount * appW)/(totalCount+1);
    CGFloat marginY = 20;
    
    for(int i = 0;i<self.apps.count;i++){
//       //读取xib文件(会创建xib中的描述的所有对象,并且按照顺序放到数组中返回)
//        NSBundle *bundle = [NSBundle mainBundle];
//        NSArray *objs = [bundle loadNibNamed:@"ZXHAppView" owner:nil options:nil];
//        UIView *appView = [objs lastObject];
        
        //创建view
        ZXHAppView *appView = [ZXHAppView appViewWithApp:self.apps[i]];
        //添加到view
        [self.view addSubview:appView];
        //设置frame
        int row = i / totalCount;
        int col = i % totalCount;
        CGFloat appX = marginX + col*( appW + marginX) ;
        CGFloat appY = 30 + row * ( appH + marginY);
        appView.frame = CGRectMake(appX, appY, appW, appH);
        
//        //获取数据
//        ZXHApp *app = self.apps[i];
//        //设置图片
//        //UIImageView *iconView = appView.subviews[0];
//        UIImageView *iconView = (UIImageView *)[appView viewWithTag:10];
//        iconView.image = [UIImage imageNamed:app.icon];
//        //设置文字
//        //UILabel *nameLabel = appView.subviews[1];
//        UILabel *nameLabel = (UILabel *)[appView viewWithTag:20];
//        nameLabel.text = app.name;

    }
    
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/** 实现懒加载初始化信息*/
-(NSArray *)apps{
    if (_apps == nil) {
        //获取plist全路径
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];
        //加载数据
        NSArray *appArray = [NSArray arrayWithContentsOfFile:path];
        //将dictArray里面所有字段转换为模型对象,放到心的数组中
        NSMutableArray *appMuArray = [NSMutableArray array];
        for (NSDictionary *dict in appArray) {
            //创建模型对象
            ZXHApp *app = [[ZXHApp alloc]initWithDict:dict];
            
            //将模型添加到数组中
            [appMuArray addObject:app];
        }
        _apps = appMuArray;
    }
    
    return _apps;
}
@end


实现点解下载按钮,提示“下载成功”

 

/**
 *  下载app
 *
 *  @param sender uibutton
 
    这种实现方式存在问题:耦合性强,[self.superview addSubview:label]; label添加到父窗口中,万一xib的父窗口变了就要改代码,扩展性不好。 应该采用代理方式。
 */
- (IBAction)download:(UIButton *)btn {
    //让按钮实效(文字变为“已下载”)
    btn.enabled = NO;
    
    //获取屏幕宽度和高度
    CGSize size =  [[UIScreen mainScreen]applicationFrame ].size;
    CGFloat width = size.width;
    CGFloat hegiht = size.height;

    
    //显示下载成功的信息("成功下载xxx")
    UILabel *label = [[UILabel alloc] init];
    label.text = [NSString stringWithFormat:@"成功下载%@",self.app.name];
    label.font = [UIFont systemFontOfSize:13];
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    label.backgroundColor = [UIColor blackColor];
    label.frame = CGRectMake(0, 0, 150, 25);
    label.center = CGPointMake(width * 0.5, hegiht -50);
    label.alpha = 0.5;
    
    //label圆角
    // 巧妙利用控件的尺寸和圆角半径,能产生一个圆
    label.layer.cornerRadius = 5;
    // 超出主层边界的内容统统剪掉
    //label.layer.masksToBounds = YES;
    label.clipsToBounds = YES;
    
    //添加label
    [self.superview addSubview:label];
    
    // 动画显示
    [UIView animateWithDuration:2 animations:^{
        label.alpha = 0.5; //显示
    }completion:^(BOOL finished){
        [UIView animateWithDuration:2 animations:^{
            label.alpha = 0; //不显示
        }completion:^(BOOL finished){
            [label removeFromSuperview]; //移除
        }];
    }];
    

      完整项目源码:点击打开链接


  ---------------文章至此!!奋斗


评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值