ios_添加按钮与删除按钮

Hello, 大家好,又到了周末,今天我要来分享的是一篇“字母饼干惊险记”,一个可爱的 ios 小程序。

今天只有不到两个小时的时间写这篇,为了更直观,首先我们上效果图:

ios_添加按钮与删除按钮_第1张图片

在 iPhone 7 plus 的模拟器界面,我们看到界面上方有两个可爱的瑞典字母,是我从朋友圈盗图来的,很感谢这位朋友分享好看的图片,在完成这个程序时为我带来了许多乐趣。

好啦,回归正题,这两个字母是两个按钮,可以点击的哦。每点击一次,下方的深色面板就会添加一项控件。我在这里选取的是一张图片,当然你也可以添加图片和文本的组合,这时就要用到父控件了,我们在后面也会讲到。细心的盆友们肯定会发现,咦,为什么右边是灰色的?这就说这个按钮是不可点击的 display 状态,当点击完成后,我们可以看到下面的界面:

ios_添加按钮与删除按钮_第2张图片

这时,添加按钮变为不可点击的状态,这里的控件都是依次添加的,那么这里就要涉及换行的操作。下面我们来进行代码的讲解,这个小程序与非在学的时候需要注意的点有点多哦。

在最终版的代码里,我们需要做的有四部分:

1/懒加载——加载数据的一种方式,当且仅当用到这个数据时加载一次,这样做就会加载完全部数据后再进行方法调用而增加了冗余,只有当用到这些数据时才会加载,并且在后面的程序再次用到这些数据时不用重新加载,它是不是又聪明又懒呢?所以加懒加载,懒得加载你。

2/在界面中添加按钮——这里也就是指我们那两个可爱的字母,它们的类是 UIButton 的类型,当界面加载完成后,按钮需要被创建好,可以使用代码的方式添加,但我们有一种更便捷好用的方式就是 xib,这点我们在接下来也会讲到。

3/添加和删除的方法——对这两个方法进行调用,才能将下方的图片依次添加到我们的 UIView 里。

4/检查按钮状态——这是字母饼干什么时候变为灰色不可点击状态,和什么时候满血复活的关键。

在添加方法里涉及到一个九宫格的数值计算,也就是这些图片之间的间隙怎么计算,你该不会以为是要一张一张拖上去吧?(其实我一开始就会这么以为)

    //每张图片的尺寸
    CGFloat characterW = 80;
    CGFloat characterH = 80;
    //一行的列数
    int cols = 4;
    //一列的行数
    int rows= 5;
    //列间距
    CGFloat colMargin = (self.myboard.frame.size.width - cols * characterW) / (cols - 1);
    //行间距
    CGFloat rowMargin = (self.myboard.frame.size.height - rows * characterH) / (rows - 1);

这里需要解释的是列间距与行间距的计算。其实很简单,间距就是深蓝色的界面宽度减去你所拥有的 n 张图片总宽度,将剩下的宽度分给 n-1 个空隙。然后根据索引分别计算出每张图片的横纵坐标:

    NSUInteger col = index % cols;
    CGFloat characterX = col * (characterW + colMargin);

    NSUInteger row = index / cols;
    CGFloat characterY = row * (characterH + rowMargin);

计算机会帮你计算每次点击后那张图片该放在哪个位置,这时你只有要用它能懂的方法把图片放在相应的位置就好。

在这个小程序里我们采用完全面向模型的方法加载数据,也就是说在懒加载的时候,我们从 .plist 文件加载的是一个字典数组,即这个数组里装的都是字典,我们需要将它们转成模型,在数据加载的那一刻就转换完成:

-(NSArray *)chars
{
    if(_chars == nil){
        NSArray *charsArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"chars" ofType:@"plist"]];
        NSMutableArray *chArray = [NSMutableArray array];
        for(NSDictionary *ch in charsArray){
            chs *cModel = [chs charWithCh:ch];
            [chArray addObject:cModel];
        }
        _chars = chArray;
    }
    return _chars;
}

这里需要注意的一点是,在用懒加载时,我们利用 mainBundle 获得 .plist 文件的全路径。这个方法以后也会多次用到。

这里的模型是什么等模型呢?好问题。我们这就来看一下,原来它是在 xib 里直接使用 UIImageView 设好的,这里有一句关键的代码是:

charView *myboard = [charView myboard];

这里不应该是 UIView 吗?charView 能用吗?小心哦,这里的确是个雷区,要想让你的模型好使(哎呀东北话都跑出来了就是这个意思),你需要将这里的类写为继承自UIView的接口,也就是charView,charView 是一个自定义的类名,在哪里有呢?就在xib文件里的View,注意:是最上方的 View 控件需要改,别改那一小块区域的类(我才不说我改了好半天才发现错呢)。与非在这里费了一些无用功,还以为是代码错了呢。之所以改整体的,是因为它从大窗口那里继承后,才会再加载里面的小东西。

ios_添加按钮与删除按钮_第3张图片

面向模型的好处是:根据索引从数组里取出的就是模型。这时,从模型直接获取图片,再添加到子视图即可,是不是方便了很多呢?这里要注意的一点是我们要用 CGRectMake 设置好尺寸,图片才会显示出来,否则你可能什么都看不到会很失望,记得检查一下是否设置好了尺寸让它显现。

添加方法到这里就差不多完成了,什么?还有删除方法?别担心,删除方法意外的只有短短一行代码:

   [[self.myboard.subviews lastObject] removeFromSuperview];

移除最后一项?竟然还有这种操作?! 太简单了吧,你有想到吗?

好的,你想到了,我们继续下一项。我们给它删删删删……

ios_添加按钮与删除按钮_第4张图片

好了,它中间状态就是这样的,好想给大家展示动图啊,在鼠标点击的时候,有一个高亮状态,你会看到字母饼干惊悚的表情,系统自带?开什么玩笑,这么好看的效果当然是我加了一个渐变映射在上面,瞬间变彩色,好吧是没什么用,看着开心啊有木有呢。那么,我要说重点了,这里的这些按钮也是控件,你要对一个它进行操作,首先你要拿到它,怎么拿呢,你对它进行操作,一定是想改变它的属性对不对,那么你就要先拥有这个属性:

@property(weak,nonatomic) UIButton *addBtn;

然后……拖线,对~!就是拖线,按住 control(mac上的写着 control 字的键哦)。要让它有惊悚的效果:高亮状态的奇异彩色,不可点击状态的灰色,平时的可爱样子,你需要在获得这个按钮后为它添加 3 张不同的图片:

self.addBtn = [self addButtonWithImage:@"img-a" highImage:@"A-light" disabledImage:@"img-ah" frame:CGRectMake(20, 20, 40, 40) action:@selector(add)];

竟然是只是变换图片?对的,就是这么 low,最后我们在讲讲 HUD,那是什么?我们上图:

ios_添加按钮与删除按钮_第5张图片

ok, fine?Ok,就是这层透明指示层,是不是整个界面瞬间复杂了?而它在你设定的秒数过去后就可以消失,自动消失?是的,但是需要我们用设置透明度的方式来让它消失:

            self.HUD.alpha = 1.0; 
            self.HUD.text = @"ok,fine";
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                self.HUD.alpha = 0.0;

dispatch_after() 就是让它消失的咒语,来跟我读一遍,dispatch after 消失!

好的,今天的总结就到这里,我们下周再见!

后记:
还有十几分钟,我就要欢快的运动去啦(睡前玩手机运动),在结束之前,我还要提几个问题。在这个小程序里,涉及到了封装的概念,初步接触,觉得这的确是一个非常神奇有用的东西,还需要进一步的学习,我自己也没搞懂,所以今天的总结中没有提及,但在之后的某一篇文章必然会有它的。

谢谢大家!源代码附上(竟然写完了……):

#import "ViewController.h"
#import "chs.h"
#import "charView.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myboard;
/**添加按钮*/
@property(weak,nonatomic) UIButton *addBtn;
/**删除按钮*/
@property(weak,nonatomic) UIButton *removeBtn;
/**全部数据*/
@property(strong,nonatomic) NSArray *chars;
/**HUD显示器*/
@property (weak, nonatomic) IBOutlet UILabel *HUD;

@end

@implementation ViewController

#pragma mark 懒加载:加载plist数据 
-(NSArray *)chars
{
    if(_chars == nil){
        NSArray *charsArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"chars" ofType:@"plist"]];

        NSMutableArray *chArray = [NSMutableArray array];
        for(NSDictionary *ch in charsArray){
            chs *cModel = [chs charWithCh:ch];
            [chArray addObject:cModel];
        }
        _chars = chArray;
    }
    return _chars;
}

-(void)viewDidLoad
{
    [super viewDidLoad];

    //加入“添加按钮”
    self.addBtn = [self addButtonWithImage:@"img-a" highImage:@"A-light" disabledImage:@"img-ah" frame:CGRectMake(20, 20, 40, 40) action:@selector(add)];
    //加入“删除按钮‘
    self.removeBtn = [self addButtonWithImage:@"img-q" highImage:@"Q-light" disabledImage:@"img-qh" frame:CGRectMake(360, 20, 40, 40) action:@selector(remove)];
    self.removeBtn.enabled = NO;
}

#pragma mark 添加按钮
-(UIButton *)addButtonWithImage:(NSString *)Image highImage:(NSString *)highImage disabledImage:(NSString *)disabledImage frame:(CGRect)frame action:(SEL)act
{
    //创建按钮
    UIButton *btn=[[UIButton alloc] init];
    //设置背景图片
    [btn setBackgroundImage:[UIImage imageNamed:Image] forState:UIControlStateNormal];
    [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
    [btn setBackgroundImage:[UIImage imageNamed:disabledImage] forState:UIControlStateDisabled];
    //设置位置和尺寸
    btn.frame=frame;
    //监听按钮点击
    [btn addTarget:self action:act forControlEvents:UIControlEventTouchUpInside];
    //添加按钮
    [self.view addSubview:btn];

    return btn;
}

#pragma mark 添加
-(void)add
{
    CGFloat characterW = 80;
    CGFloat characterH = 80;

    int cols = 4;
    int rows= 5;

    CGFloat colMargin = (self.myboard.frame.size.width - cols * characterW) / (cols - 1);
    CGFloat rowMargin = (self.myboard.frame.size.height - rows * characterH) / (rows - 1);

    charView *myboard = [charView myboard];

    NSUInteger index = self.myboard.subviews.count;
    myboard.mychar = self.chars[index];
    NSUInteger col = index % cols;
    CGFloat characterX = col * (characterW + colMargin);
    NSUInteger row = index / cols;
    CGFloat characterY = row * (characterH + rowMargin);

    chs *cModel = self.chars[index];

    //获取图片
    UIImageView *character = [[UIImageView alloc] init];
    character.image=[UIImage imageNamed:cModel.character];

    character.frame=CGRectMake(characterX, characterY, characterW, characterH);
    [self.myboard addSubview:character];

    //控制按钮的状态
    [self checkIt];

}

#pragma mark删除
-(void)remove
{
    [[self.myboard.subviews lastObject] removeFromSuperview];

    [self checkIt];
}

#pragma mark 检查按钮状态
-(void)checkIt
{
    self.addBtn.enabled = (self.myboard.subviews.count < self.chars.count);
    self.removeBtn.enabled = (self.myboard.subviews.count != 0);

    /**显示HUD*/
    if(self.removeBtn.enabled == NO){
        self.HUD.alpha = 1.0;
        self.HUD.text = @"I came running";
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.HUD.alpha = 0.0;
        });
        }else if(self.addBtn.enabled == NO){
            self.HUD.alpha = 1.0; 
            self.HUD.text = @"ok,fine";
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                self.HUD.alpha = 0.0;
            });
    }
}
@end

你可能感兴趣的:(ios开发历程)