【iOS7的一些总结】12、使用UIView的一种有效方法

简介: 在一个典型的MVC结构中,Model部分负责保存目标数据,View部分主要负责实现数据的界面以及将数据显示出来,二者在Controller的操作下协同工作。

在一个典型的MVC结构中,Model部分负责保存目标数据,View部分主要负责实现数据的界面以及将数据显示出来,二者在Controller的操作下协同工作。在iOS应用中,View的实现主要由UIView及其派生类实现,主要由UILabel、UIImageView等等类来显示不同的信息。

这里展示一个demo来说明个人对UIView同数据交互的一种观点,个人意见仅供参考,欢迎讨论。

1、首先建立一个UIView的子类用于定制我们的视图对象。

头文件:

#import <UIKit/UIKit.h>

@interface UserInfoView : UIView

//@property (nonatomic,copy) NSString *imgString;
//@property (nonatomic,copy) NSString *nameString;
//@property (nonatomic,copy) NSString *addrString;
//@property (nonatomic,copy) NSString *infoString;
//@property (nonatomic,copy) NSString *countString;
//@property (nonatomic,copy) NSString *attString;
//@property (nonatomic,copy) NSString *fansString;

@property (nonatomic,retain) NSDictionary *param;

- (void)loadData;

@end
m文件:

#import "UserInfoView.h"
#import "RectButton.h"

@interface UserInfoView()

//UI控件
@property (nonatomic,retain) UIImageView    *userImage;
@property (nonatomic,retain) UILabel        *nameLabel;
@property (nonatomic,retain) UILabel        *addressLabel;
@property (nonatomic,retain) UILabel        *infoLabel;
@property (nonatomic,retain) UILabel        *countLabel;
@property (nonatomic,retain) RectButton     *attButton;
@property (nonatomic,retain) RectButton     *fansButton;
@property (nonatomic,retain) UIButton       *profileButton;
@property (nonatomic,retain) UIButton       *moreButton;

//数据成员
//@property (nonatomic,copy) NSString *imgString;
@property (nonatomic,copy) NSString *nameString;
@property (nonatomic,copy) NSString *addrString;
@property (nonatomic,copy) NSString *infoString;
@property (nonatomic,copy) NSString *countString;
//@property (nonatomic,copy) NSString *attString;
//@property (nonatomic,copy) NSString *fansString;

@end

@implementation UserInfoView

- (id)init
{
    CGRect frameRect = CGRectMake(0, 0, 320, 200);
    self = [self initWithFrame:frameRect];
    if (self)
    {
        NSLog(@"Init called");
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColor lightGrayColor];
        
        _userImage = [[UIImageView alloc] initWithFrame:CGRectZero];
        [self addSubview:_userImage];

        _nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [self addSubview:_nameLabel];

        _addressLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [self addSubview:_addressLabel];

        _infoLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [self addSubview:_infoLabel];

        _attButton = [[RectButton alloc] initWithFrame:CGRectZero];
        [self addSubview:_attButton];
        
        _fansButton = [[RectButton alloc] initWithFrame:CGRectZero];
        [self addSubview:_fansButton];
        
        _profileButton = [[UIButton alloc] initWithFrame:CGRectZero];
        [self addSubview:_profileButton];
        
        _moreButton = [[UIButton alloc] initWithFrame:CGRectZero];
        [self addSubview:_moreButton];
        
        _countLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [self addSubview:_countLabel];
    }
    return self;
}

- (void)setParam:(NSDictionary *)param
{
    _param = param;
    
    _nameString = [_param objectForKey:@"Name"];
    _addrString = [_param objectForKey:@"Address"];
    _infoString = [_param objectForKey:@"Infomation"];
    _countString = [_param objectForKey:@"Count"];
    
    [self loadData];
}

- (void)layoutSubviews
{
    _userImage.frame = CGRectMake(20, 20, 80, 80);
    _userImage.backgroundColor = [UIColor yellowColor];
    
    _nameLabel.frame = CGRectMake(120, 20, 180, 20);
    _nameLabel.backgroundColor = [UIColor yellowColor];
    
    _addressLabel.frame = CGRectMake(120, 50, 180, 20);
    _addressLabel.backgroundColor = [UIColor yellowColor];
    
    _infoLabel.frame = CGRectMake(120, 80, 180, 20);
    _infoLabel.backgroundColor = [UIColor yellowColor];
    
    _attButton.frame = CGRectMake(20, 110, 60, 60);
    _attButton.backgroundColor = [UIColor greenColor];
    
    _fansButton.frame = CGRectMake(93, 110, 60, 60);
    _fansButton.backgroundColor = [UIColor greenColor];

    _profileButton.frame = CGRectMake(167, 110, 60, 60);
    _profileButton.backgroundColor = [UIColor greenColor];

    _moreButton.frame = CGRectMake(240, 110, 60, 60);
    _moreButton.backgroundColor = [UIColor greenColor];

    _countLabel.frame = CGRectMake(20, 180, 280, 15);
    _countLabel.backgroundColor = [UIColor whiteColor];
    
    [self loadData];
}

- (void)loadData
{
    if (self.nameString.length != 0)
    {
        _nameLabel.text = self.nameString;
    }
    if (self.addrString.length != 0)
    {
        _addressLabel.text = self.addrString;
    }
    if (self.infoString.length != 0)
    {
        _infoLabel.text = self.infoString;
    }
    if (self.countString.length != 0)
    {
        _countLabel.text = self.countString;
    }
}

@end

在这个UserInfoView新建的时候,在initWithFrame中建立各个子视图,但是只是单纯新建一个对象而已,其frame设置为0。另外,还重写了init函数,在函数中设置了指定的View大小,这样在Controller新建视图的时候不需要指定参数直接按照指定值进行操作。


UserInfoView中各个子视图的设置,在layoutSubView中完成,包括设置子视图的frame和背景颜色。layoutSubView函数可能经常被调用到,主要由以下几种情况:

  1. 当addSubView被调用时,被添加视图以及其子视图的layoutSubView会被调用;
  2. 当视图的frame发生改变时,会调用该视图的layoutSubView;
  3. 当滚动UIScrollView的时候会调用该视图及其父视图的layoutSubView;
  4. 旋转设备的时候;
  5. 向该视图发送setNeedLayout消息的时候。

2、由Controller向View中发送数据。

ViewController类的实现如下:

#import "ViewController.h"
#import "UserInfoView.h"

@interface ViewController ()

@property (nonatomic,retain) UIButton *People1;
@property (nonatomic,retain) UIButton *People2;
@property (nonatomic,retain) UserInfoView *userView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
     _userView = [[UserInfoView alloc] init];
    [self.view addSubview:_userView];
    
    _People1 = [UIButton buttonWithType:UIButtonTypeSystem];
    _People1.frame = CGRectMake(20, 240, 120, 40);
    [_People1 setTitle:@"张三" forState:UIControlStateNormal];
    _People1.backgroundColor = [UIColor lightGrayColor];
    [_People1 addTarget:self action:@selector(setPeople1Data) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_People1];
    
    _People2 = [UIButton buttonWithType:UIButtonTypeSystem];
    _People2.frame = CGRectMake(180, 240, 120, 40);
    [_People2 setTitle:@"李四" forState:UIControlStateNormal];
    _People2.backgroundColor = [UIColor lightGrayColor];
    [_People2 addTarget:self action:@selector(setPeople2Data) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_People2];
    
/*    view.nameString = @"张三";
    view.addrString = @"北京";
    view.infoString = @"学生";
    view.countString = @"12345";
    
    view.nameString = @"李四";
    view.addrString = @"上海";
    view.infoString = @"工程师";
    view.countString = @"54321";*/
}

- (void)setPeople1Data
{
    NSLog(@"setPeople1Data called.");
    NSDictionary *param = @{@"Name": @"张三", @"Address" : @"北京", @"Infomation" : @"学生", @"Count" : @"12345"};
    _userView.param = param;
}

- (void)setPeople2Data
{
    NSLog(@"setPeople2Data called.");
    NSDictionary *param = @{@"Name": @"李四", @"Address" : @"上海", @"Infomation" : @"工程师", @"Count" : @"54321"};
    _userView.param = param;
}

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

@end

ViewController的默认视图上,分别实现了两个按钮并分别设置了响应函数。我们的目的是通过选择不同的按钮来改变UserInfoView中显示的数据。从两个响应函数setPeople1Data和setPeople2Data的实现可知,UserInfoView所需要的信息都被封装在了一个字典型变量param中,对view的修改仅仅做了一个操作,即将该字典变量赋给了UserInfoView实例的一个property,通过这种改变一下目标view属性的方式即可完成对显示信息的更改。这样,Controller并不关心UserInfoView实例是如何解析字典参数的,也不需要对该实例进行其他操作,当需要更新数据的时候只需要一次赋值就可以了。如此可以最大程度地解除Controller和View的耦合性,提高代码的逻辑简洁度和可复用性。

再回到UserInfoView类中的实现方法。如何实现在字典类property改变的同时对自己的子视图进行重写数据操作呢?方法很简单。首先将重写子视图数据的代码分离到loadData函数中,然后重写NSDictionary *param这个property的set方法(即setParam),然后在该set方法和layoutSubView方法中调用loadData方法就可以了。

demo下载链接:点这里

目录
相关文章
|
7月前
|
移动开发 前端开发 数据安全/隐私保护
iOS发布证书.p12文件无密码解决办法及导出带密码的新.p12文件方法
iOS发布证书.p12文件无密码解决办法及导出带密码的新.p12文件方法
206 0
|
7月前
|
安全 编译器 开发工具
​iOS安全加固方法及实现
​iOS安全加固方法及实现
71 0
​iOS安全加固方法及实现
|
7月前
|
存储 监控 iOS开发
iOS应用崩溃了,如何通过崩溃手机连接电脑查找日志方法
在iOS应用开发过程中,调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时,我们可以连接电脑并使用Xcode Console等工具来查看日志。然而,这种方式可能不够方便,并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了极大的便利,本文将详细介绍其功能和使用方法。 克魔助手会提供两种日志,一种是实时的,一种的是崩溃的。(由于崩溃日志的环境很麻烦,目前只展示实时日志操作步骤)
|
7月前
|
存储 iOS开发 开发者
使用克魔助手进行iOS数据抓包和HTTP抓包的方法详解
使用克魔助手进行iOS数据抓包和HTTP抓包的方法详解
105 0
|
iOS开发 开发者
📝 App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
在iOS应用程序开发过程中,进行App备案并获取公钥及证书SHA-1指纹是至关重要的步骤。本文将介绍如何通过appuploader工具获取iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹,帮助开发者更好地理解和应用该过程。
|
7月前
|
小程序 前端开发 Android开发
解决小程序中textarea ios端样式不兼容的两种方法
解决小程序中textarea ios端样式不兼容的两种方法
214 0
|
10天前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
19 2
|
4月前
|
语音技术 开发工具 图形学
Unity与IOS⭐一、百度语音IOS版Demo调试方法
Unity与IOS⭐一、百度语音IOS版Demo调试方法
|
4月前
|
iOS开发
App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
203 0
App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
|
7月前
|
Android开发 iOS开发 开发者
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
415 0