zoukankan      html  css  js  c++  java
  • iOS学习3_UI开发之纯代码/storyboard/xib

    由于做android开发时间比较长,按照android的经验,一般开发界面都是使用xml来写布局文件的,很少会完全使用代码来写布局,最近刚学iOS,发现好多都是直接使用代码来写布局的。看视频学习刚好看到这个不错的小项目,因此做了一点小小的整理。

    要实现的效果如下,点击加号添加一条,点击回收投标删除最下面一条,点击删除会删除当前的一条。点击头片会更改中间的文字。删除/添加会伴随动画。


    1.使用纯代码来写布局


    点击添加按钮

    - (IBAction)add:(UIBarButtonItem *)sender{
        UIView * v = [self getRowView];
        UIView * lastView = [[self.view subviews] lastObject];
        NSLog(@"%@",lastView);
        CGFloat rowY = lastView.frame.origin.y + lastView.frame.size.height + 1;
        v.frame = CGRectMake(_screenWidth, rowY, _screenWidth, KHeight);
        v.alpha = 0;
        [self.view addSubview:v];
        
        [UIView animateWithDuration:0.5 animations:^{
            v.alpha = 1;
            v.frame = CGRectMake(0, rowY, _screenWidth, KHeight);
        }];
        [self.removeItem setEnabled:true];
    }

    点击回收最后面一条按钮

    - (IBAction)remove:(UIBarButtonItem *)sender
    {
        UIView * lastView = [[self.view subviews] lastObject];
    
        [UIView animateWithDuration:0.5 animations:^{
            CGRect tempF = lastView.frame;
            tempF.origin.x = _screenWidth;
            lastView.frame = tempF;
            lastView.alpha = 0;
        } completion:^(BOOL finished) {
            [lastView removeFromSuperview];
            [self.removeItem setEnabled:self.view.subviews.count > 1];
    }];
    }
    
    getRowView函数是得到一行item的布局View

    - (UIView *) getRowView
    {
    UIView * view = [[UIView alloc]init];
        view.bounds = CGRectMake(0, 0, self.view.frame.size.width, KHeight);
        [view setBackgroundColor:[UIColor grayColor]];
        
        // 创建文字
        UILabel * label = [[UILabel alloc]init];
        label.frame = CGRectMake(0, 0, self.view.frame.size.width, KHeight);
        label.text =_allNames[arc4random_uniform(_allNames.count)];
        label.textColor = [UIColor blackColor];
        label.textAlignment = NSTextAlignmentCenter;
        label.tag = 10;
        [view addSubview:label];
        
        // 创建头像
        UIButton * icon = [[UIButton alloc]init];
        icon.frame = CGRectMake(20, 0, KHeight , KHeight);
        int randomIndex = arc4random_uniform(9);
        NSString *iconName = [NSString stringWithFormat:@"01%d.png", randomIndex];
        // 设置图片
        [icon setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
        // 添加监听器
        [icon addTarget:self action:@selector(iconClick:) forControlEvents:UIControlEventTouchUpInside];
        [view addSubview:icon];
        
        // 创建删除按钮
        UIButton * deleteIcon = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [deleteIcon setCenter:CGPointMake(280, KHeight/2)];
        deleteIcon.bounds = CGRectMake(0, 0, 60 , 30);
        [deleteIcon setTitle:@"删除" forState:UIControlStateNormal];
        [deleteIcon addTarget:self action:@selector(deleteClick:) forControlEvents:UIControlEventTouchUpInside];
        [view addSubview:deleteIcon];
        return  view;
    }
    点击图片的响应函数

    - (void)iconClick:(UIButton *)btn
    {
        UILabel * label = (UILabel *)[[btn superview] viewWithTag:10];
        NSString * oriStr = [label text];
        NSString * newStr = [NSString stringWithFormat:@"%@+%@",oriStr,oriStr];
        label.text = newStr;
    }
    
    点击删除某一项的按钮

    - (void) deleteClick:(UIButton * )btn
    {
        [UIView animateWithDuration:0.5 animations:^{
            CGRect tempF = [btn.superview frame];
            tempF.origin.x = _screenWidth;
            btn.superview.frame = tempF;
        } completion:^(BOOL finished) {
            
            // 将下面的所有项向上移动
            int startIndex = [self.view.subviews indexOfObject:btn.superview];
            [btn.superview removeFromSuperview];
            [UIView animateWithDuration:0.5 animations:^{
                for (int i = startIndex; i < self.view.subviews.count; i++) {
                    UIView *child = self.view.subviews[i];
                    CGRect tempF = child.frame;
                    tempF.origin.y -= KHeight + 1;
                    child.frame = tempF;
                }
            }];
            
        }];
    }
    
    可以看出来完全使用代码来写布局非常的麻烦,使用storyboard拖控件可以通过连线的方式减少代码量,上面的代码中,添加一条item的内容非常繁琐。

    2.使用xib来作为每个item的加载布局

    好处:不需要自己使用代码进行这一行的布局

    缺点:存在的问题是还需要通过代码添加点击事件。


    加载xib文件的方式生成每一行的布局,具体如下
    - (UIView *) getRowView
    {
        NSArray * views = [[NSBundle mainBundle] loadNibNamed:@"item" owner:nil options:nil];
        UIView * view = views[0];
        
        UIButton * icon = view.subviews[0];
        UILabel * label = view.subviews[1];
        UIButton * deleteIcon = view.subviews[2];
        NSLog(@"%@ + %@ + %@",icon,label,deleteIcon);
        NSString *iconName = [NSString stringWithFormat:@"01%d.png",arc4random_uniform(9)];
        
        [icon setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
        
        label.text = _allNames[arc4random_uniform(_allNames.count)];
        [deleteIcon addTarget:self action:@selector(deleteClick:) forControlEvents:UIControlEventTouchUpInside];
        return  view;
    }

    3.使用xib和连线

    好处:不需要自己添加点击事件的触发。指定了FileOwer,FileOwer保证了可以连线,指定某个xib的FileOwer也就是指定了它的管理类。

    缺点:这样存在的问题是代码间的耦合性太高,

    理论上在创建一行时,也就是在getRowView方法里面,并不需要关注具体的细节,不需要关注他的子控件,最好的情况就是只给传递我们需要显示的数据,剩下的自己不需要处理。并且不好实现代码的复用。


    注:必须指定File’s Ower 否则无法连线,并且在使用代码加载的时候指定该参数。FileOwer并不一定要是这个类,任何一个类都是可以的。

    - (UIView *) getRowView
    {
        NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"item" owner:self options:nil];
        UIView *view = views[0];
        UIButton * icon = view.subviews[0];
        UILabel * label = view.subviews[1];
        NSString *iconName = [NSString stringWithFormat:@"01%d.png", arc4random_uniform(9)];
        [icon setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
        label.text = _allNames[arc4random_uniform(_allNames.count)];
    return view;
    }
    

    4.自定义View


    注意:这里不能指定File Owner的属性,将View的Class属性设置为我们自定义的View即可连线。

    MyView中的类方法如下

    + (MyView *) myViewWithIcon:(UIImage *)iconImage andLabel:(NSString *)labelStr
    {
        MyView *view = [[NSBundle mainBundle] loadNibNamed:@"item" owner:nil options:nil][0];
        [view.iconBtn setImage:iconImage forState:UIControlStateNormal];
        
        view.label.text = labelStr;
    
        return view;
    }
    

    这样创建一行View的代码为

    - (UIView *) getRowView
    {
        MyView * view = [MyView myViewWithIcon:[UIImage imageNamed:[NSString stringWithFormat:@"01%d.png", arc4random_uniform(9)]] andLabel:_allNames[arc4random_uniform(_allNames.count)]];
    return view;
    }
    

    使用MyView来创建一行View时就可以完全和其他的代码分开,因为处理它的子控件的业务全部由他自己来处理。

    以上内容整理自视频

  • 相关阅读:
    压缩与解压缩 ZipHelper
    ESFramework介绍之(15)-- IRAS
    ESFramework介绍之(8)-- 客户端插件IPassiveAddin
    使用Eclipse开发Jsp
    深入探讨 java.lang.ref 包
    java多线程总结二
    模拟弹子台球java多线程应用
    简单的邮件客户端
    最近创办了一个java学习邮件列表
    优秀的XML~~Altova XMLSpy 2010英文企业版+有效破解方法
  • 原文地址:https://www.cnblogs.com/qhyuan1992/p/5385305.html
Copyright © 2011-2022 走看看