黑马程序员_iOS 的基础控件之xib

iOS,Android,Java培训,期待与您的交流
iOS应用开发的一项内容就是用户界面的开发。不管应用程序实际包含的逻辑有多复杂,如果这个应用程序没有提供友好的图形用户界面,將很难吸引用户。作为一个程序设计者,必须优先考虑用户的感受,一定要让用户感到爽,这个应用程序才有价值。
xib是早期iOS开发的界面设计文件,从iOS5开始,Xcode使用比xib更近一步的StoryBoard来设计UI界面。但是xib并没有被淘汰,在iOS开发中,某些界面的开发必须用到xib。总体而言,storyboard和xib的用法遵循如下规则:
storyboard,描述软件界面,大范围,重量级,比较适合整个软件的所有界面
xib:描述软件界面,小范围,轻量级,适合描述小界面
1    xib的基本使用
xib的使用与StroyBoard大同小异,一样需要拖控件到界面。但需要特别注意的时,xib文件有一个file owner选项。该file owner一般是一个类,xib中控件的事件监听方法必须是该file owner的方法,即如果没有指定file owner是没法用连线指定控件的监听方法(可以用addTarget方法)。用代码加载xib文件时,也要指定一个file owner对象。两个file onwer的意义不同,前者是为了绑定监听方法,后者是运行时,系统才会真正调用在代码中指定的file owner的监听方法。下面是一个xib的界面,只包含一个按钮,指定该xib的file owner是一个Dog类,监听方法是- (IBAction)btnClick;
黑马程序员_iOS 的基础控件之xib_第1张图片
用代码加载xib时,可以指定file owner为Dog实例,也可以不指定。如果不指定,单击按钮时,将会调用nil的btnClick;方法,会导致EXC_BAD_ACCESS错误。也不能指定局部变量,因为局部变量在它所在的方法结束后,该局部变量就不存在了,也会导致EXC_BAD_ACCESS错误
  
- (void)viewDidLoad
{
    [super viewDidLoad];

    _d1 = [[Dog alloc] init]; //成员变量 
    _d1.age = 10;
    
    _d2 = [[Dog alloc] init];  //成员变量
    _d2.age = 20;
   
    Dog *d = [[Dog alloc] init];  //局部变量

    //加载xib文件,xib的file owner不能是局部变量。file owner也能为空,但会导致EXC_BAD_ACCESS错误
    UIView *blueView = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:_d2 options:nil][0];
    //UIView *blueView = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:nil options:nil][0];
    

     blueView.center = CGPointMake(160, 200);
    [self.view addSubview:blueView];
}

2    xib的重用
给xib指定file owner,降低了程序的耦合性。而且在程序中硬编码,加载xib文件,也不是一个好的编程方式。可以將xib抽象成一个类,调用该类的某个方法创建xib。以下面的xib界面为例,说明如何重用xib。
该界面的左边是一个图片按钮,中间是UILabel,右边是删除按钮。只要指定图片按钮的图片,和UILabel的现实文本,就能得到该xib代表的界面。
  
//RowView.h
@interface RowView : UIView

//类方法,用于创建xib界面
+ (id)rowViewWithIcon:(NSString *)icon name:(NSString *)name;


@property (nonatomic, weak) IBOutlet UIButton *iconBtn; //图片按钮

@property (nonatomic, weak) IBOutlet UILabel *nameLabel;  //联系人姓名

@end

//RowView.m
@implementation RowView

+ (id)rowViewWithIcon:(NSString *)icon name:(NSString *)name
{
    RowView *view = [[NSBundle mainBundle] loadNibNamed:@"RowView" owner:nil options:nil][0];
    
    // 1.设置图标
//    UIButton *iconBtn = (UIButton *)[view viewWithTag:1];
    [view.iconBtn setImage:[UIImage imageNamed:icon] forState:UIControlStateNormal];
    
    // 2.设置姓名
//    UILabel *nameLabel = (UILabel *)[view viewWithTag:2];
    view.nameLabel.text = name;
    
    return view;
}



@end

3    联系人管理
用一个联系人管理的实例,说明如何应用xib和StoryBoard开发应用程序。联系人管理的界面如下图所示。
黑马程序员_iOS 的基础控件之xib_第2张图片
上图的UIToolBar是固定的,可以用StroyBoard创建,红色的联系人信息是不断变化,用xib创建。该xib对应的类已经在上文给出。当点击添加按钮时,增加一条联系人信息,通过监听事件方法实现。
  
#pragma mark 添加一行
- (IBAction)add:(UIBarButtonItem *)sender {
    // 0.取出最后一个子控件
    UIView *last = [self.view.subviews lastObject];
    // 这行的Y = 最后一个子控件的Y + 最后一个子控件的高度 + 间距
    CGFloat rowY = last.frame.origin.y + last.frame.size.height + 1;
    
    // 1.创建一行
    UIView *rowView = [self createRowView];
    
    // 2.添加一行到控制器的view中
    [self.view addSubview:rowView];
    
    // 3.让删除item有效
    _removeItem.enabled = YES;
    
    // 4.执行动画
    rowView.frame = CGRectMake(320, rowY, 320, kRowH);
    rowView.alpha = 0;
    
    // 4.1.开始动画
    [UIView animateWithDuration:kDuration animations:^{
        rowView.frame = CGRectMake(0, rowY, 320, kRowH);
        rowView.alpha = 1;
    }];
}

#pragma mark 创建一行(从xib中加载一行的view)
// xib == nib
- (UIView *)createRowView
{
    NSString *icon = [NSString stringWithFormat:@"01%d.png", arc4random_uniform(9)];
    NSString *name = _allNames[arc4random_uniform(_allNames.count)];
    
    RowView *rowView = [RowView rowViewWithIcon:icon name:name];
    
    return rowView;
}

点击UIToolBar的删除按钮,删除最后一个联系人,监听事件方法如下。
  
#pragma mark 删除一行
- (IBAction)remove:(UIBarButtonItem *)sender {
    // 1.取出最后一个子控件
    UIView *last = [self.view.subviews lastObject];
    
    [UIView animateWithDuration:kDuration animations:^{
        CGRect tempF = last.frame;
        tempF.origin.x = 320;
        last.frame = tempF;
        
        last.alpha = 0;
    } completion:^(BOOL finished) {
        [last removeFromSuperview];
        
        // 剩下的子控件个数 > 1就能够点击“删除”
        _removeItem.enabled = self.view.subviews.count > 1;
    }];
}
点击联系人信息的删除按钮,删除该行,后面的行自动向上填充。
  
#pragma mark 监听删除按钮点击
- (void)deleteClick:(UIButton *)btn
{
    [UIView animateWithDuration:kDuration animations:^{
        CGRect tempF = btn.superview.frame;
        tempF.origin.x = 320;
        btn.superview.frame = tempF;
        
        btn.superview.alpha = 0;
    } completion:^(BOOL finished) {
        // 1.获得即将删除的这行在数组中的位置
        int startIndex = [self.view.subviews indexOfObject:btn.superview];
        
        // 2.删除当前行
        [btn.superview removeFromSuperview];
        
        [UIView animateWithDuration:0.3 animations:^{
            // 3.遍历后面的子控件
            for (int i = startIndex; i 1;
    }];
}
iOS,Android,Java培训,期待与您的交流

你可能感兴趣的:(iOS)