【iOS开发-51】案例学习:动画新写法、删除子视图、视图顺序、延迟方法、button多功能使用方法及icon图标和启动页设置

案例效果:

(1)导入所需的素材,然后用storyboard把上半截位置和大小相对固定的东西布局起来。当然,这些控件也要定义成对应地IBOutlet和IBAction方便兴许使用它们。

注意:本案例在3.5inch设备上显示最佳,所以须要设置一下。

(2)首先实现点击“下一题”的功能

- (IBAction)nextQuestion {
    //1、序号添加
    self.index++;
    //2、依据序号拿到相应的模型(对象)
    NSQuestion *question=self.questions[self.index];
    //3、设置文本以及图像
    self.noLabel.text=[NSString stringWithFormat:@"%d/%d",self.index+1,self.questions.count];
    self.titleLabel.text=question.title;
    [self.iconBtn setImage:[UIImage imageNamed:question.icon] forState:UIControlStateNormal];
    //4、推断button是否失效
    self.nextQuestionBtn.enabled=self.index!=(self.questions.count-1);
    //5、加入正确答案
    [self addAnswerBtn:question];
    //6、加入option选项
    [self addOptionBtn:question];
}

当然,在viewLoad中要让视图显示第一个页面,须要例如以下:

- (void)viewDidLoad {
    self.index=-1;
    [self nextQuestion];
    [super viewDidLoad];
}

然后一个个实现nextQuestion方法中提到的那些方法。

(3)定义一个数据模型类,就是将字典转化成模型

在NSQuestion.h中:

#import <Foundation/Foundation.h>

@interface NSQuestion : NSObject
@property(nonatomic,copy) NSString *answer;
@property(nonatomic,copy) NSString *title;
@property(nonatomic,copy) NSString *icon;
@property(nonatomic,strong) NSArray *options;

-(instancetype)initWithDic:(NSDictionary *)dict;
+(instancetype)questionWithDic:(NSDictionary *)dict;
@end

在NSQuestion.m中:

#import "NSQuestion.h"

@implementation NSQuestion

-(instancetype)initWithDic:(NSDictionary *)dict{
    if ([super init]) {
        self.answer=dict[@"answer"];
        self.title=dict[@"title"];
        self.icon=dict[@"icon"];
        self.options=dict[@"options"];
    }
    return self;
}

+(instancetype)questionWithDic:(NSDictionary *)dict{
    return [[self alloc]initWithDic:dict];
}

@end

在ViewController.m中转化成模型:

#import "ViewController.h"
#import "NSQuestion.h"

@interface ViewController ()
@property(nonatomic,strong) NSArray *questions;
@end

@implementation ViewController

-(NSArray *)questions{
    if (_questions==nil) {
        NSArray *arr1=[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"questions.plist" ofType:nil]];
        NSMutableArray *questionArray=[[NSMutableArray alloc]init];
        for (NSDictionary *dic1 in arr1) {
            NSQuestion *question=[[NSQuestion alloc]initWithDic:dic1];
            [questionArray addObject:question];
        }
        _questions=questionArray;
    }
    return _questions;
}

(4)addAnswerBtn方法

-(void)addAnswerBtn:(NSQuestion *)question{
    //5、加入正确答案
    //先删除上一题的answer
    //让数组中的全部对象都运行相同地方法。用以下这一句取代以下的for循环
    [self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
//    for (UIView *subViews in self.answerView.subviews) {
//        [subViews removeFromSuperview];
//    }
    //然后再加入新的answer,依据答案的长度来加入
    int length=question.answer.length;
    for (int i=0; i<length; i++) {
        UIButton *answerBtn=[[UIButton alloc]init];
        [answerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];//设置文字颜色,否则默认白色于背景相同
        [answerBtn setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal];
        [answerBtn setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState:UIControlStateHighlighted];
        CGFloat answerMargin=10;
        CGFloat answerW=35;
        CGFloat answerH=35;
        CGFloat answerX=(self.view.frame.size.width-length*answerW-(length-1)*answerMargin)/2+i*(answerW+answerMargin);
        answerBtn.frame=CGRectMake(answerX, 0, answerW, answerH);
        [self.answerView addSubview:answerBtn];

        //监听点击事件
        [answerBtn addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside];
    }
}

这个点击事件的方法:

-(void)answerClick:(UIButton *)answerBtn{
    //让答案button文字相应的button显示出来,用for遍历
    //获取button文字用currentTitle
//    NSString *answerTitle=[answerBtn titleForState:UIControlStateNormal];
    for (UIButton *optionBtn in self.optionView.subviews) {
//        NSString *optionTitle=[optionBtn titleForState:UIControlStateNormal];
        //推断哪个optionbutton再显示出来。并且这个button本身是隐藏的,由于option里可能有同样的文字
        if ([answerBtn.currentTitle isEqualToString:optionBtn.currentTitle] && optionBtn.hidden==YES) {
            optionBtn.hidden=NO;
            break;
        }
    }
    //点击的button文字消失,由于这个文字上面须要用到比較,所以比較晚,再把文字去除
    [answerBtn setTitle:nil forState:UIControlStateNormal];

    //点击随意一个button。相当于去除文字,那么答案就不是正确答案,文字颜色回复黑色
    for (UIButton *answerBtn in self.answerView.subviews) {
        [answerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    }
}

(4)addOptionBtn方法

-(void)addOptionBtn:(NSQuestion *)question{
    //6、加入option选项
    //也是先删除再加入,相同用一句取代for循环
    [self.optionView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
//    for (UIView *subViews in self.optionView.subviews) {
//        [subViews removeFromSuperview];
//    }
    int count=question.options.count;
    int totalColumn=7;
    for (int i=0; i<count; i++) {
        UIButton *optionBtn=[[UIButton alloc]init];
        [optionBtn setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
        [optionBtn setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted];
        CGFloat optionMargin=10;
        CGFloat optionW=35;
        CGFloat optionH=35;
        int row=i/7;
        int col=i%7;
        CGFloat optionX=(self.view.frame.size.width-totalColumn*optionW-(totalColumn-1)*optionMargin)/2+col*(optionW+optionMargin);
        CGFloat optionY=row*(optionH+optionMargin);
        optionBtn.frame=CGRectMake(optionX, optionY, optionW, optionH);
        [optionBtn setTitle:question.options[i] forState:UIControlStateNormal];
        [optionBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [self.optionView addSubview:optionBtn];

        //button点击
        [optionBtn addTarget:self action:@selector(optionClick:) forControlEvents:UIControlEventTouchUpInside];
    }
}

这个监听事件方法:

-(void)optionClick:(UIButton *)optionBtn{
    //1、被点击的button消失
    optionBtn.hidden=YES;//不能删除,由于还要显示,所以用隐藏
    //2、显示文字到正确答案上去(第一个没有文字的answerbutton)
    //这里设置完,无法查看效果,是由于answer的文字默认是白色,于背景同样
    for (UIButton *answerBtn in self.answerView.subviews) {
        //推断是否有文字
//        NSString *answerTitle=[answerBtn titleForState:UIControlStateNormal];
        if (answerBtn.currentTitle.length==0) {
            [answerBtn setTitle:[optionBtn titleForState:UIControlStateNormal] forState:UIControlStateNormal];
            break;//找到后就通知for的遍历
        }
    }
    //每点击一个optionbutton就推断这个答案是否已经填满,并推断是否正确
    BOOL full=YES;
    NSMutableString *tempAnswerTitle=[NSMutableString string];
    for (UIButton *answerBtn in self.answerView.subviews){
//        NSString *answerTitle=[answerBtn titleForState:UIControlStateNormal];
        if (answerBtn.currentTitle.length==0) {//说明答案没有满
            full=NO;
        }
        //拼接文字
        if (answerBtn.currentTitle) {
            [tempAnswerTitle appendString:answerBtn.currentTitle];
        }
    }
    //假设答案满了,则推断是否正确
    if (full) {
        NSQuestion *question=self.questions[self.index];
        if ([tempAnswerTitle isEqualToString:question.answer]) {
            for (UIButton *answerBtn in self.answerView.subviews) {
                [answerBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
            }
            //推断正确后
            //先拿到当前分,再加分
            [self addScore:100];
//            int score=[self.scoreBtn titleForState:UIControlStateNormal].intValue;
//            score+=100;
//            [self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal];
            //延迟运行:跳到下一题
            //直接用[self nextQuestion];会马上跳转
            [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5];
        }else{
            for (UIButton *answerBtn in self.answerView.subviews) {
                [answerBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
            }
        }
    }
}

这里面用到一个addScore计算分数的方法:

-(void)addScore:(int)dealtScore{
    int score=[self.scoreBtn titleForState:UIControlStateNormal].intValue;
    score+=dealtScore;
    [self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal];
}

(5)对应的,点击“提示”产生的效果,是清空answer。给第一个字,并扣分

- (IBAction)tip {
    //1、先清空answer。也就是点击answer的button。就相当于清空
    for (UIButton *answerBtn in self.answerView.subviews) {
        [self answerClick:answerBtn];
    }
    //2、取出正确答案
    NSQuestion *question=self.questions[self.index];
    //3、取出正确答案的第一个字符
    NSString *firstAnswer=[question.answer substringToIndex:1];
    //4、推断并从option中取出
    for (UIButton *optionBtn in self.optionView.subviews) {
        if ([optionBtn.currentTitle isEqualToString:firstAnswer]) {
            [self optionClick:optionBtn];
            break;
        }
    }
    //5、扣分
    [self addScore:-500];
//    int score=[self.scoreBtn titleForState:UIControlStateNormal].intValue;
//    score-=500;
//    [self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal];
}

(6)点击“大图”的效果。加入一个阴影,调整图像顺序。并让图片和阴影等动画变动

- (IBAction)bigImg {

    //1、加入一个半透明阴影
    UIButton *cover=[[UIButton alloc]init];
    cover.frame=self.view.bounds;
    cover.backgroundColor=[UIColor blackColor];
    cover.alpha=0;
    [cover addTarget:self action:@selector(smallImg) forControlEvents:UIControlEventTouchUpInside];
    self.cover=cover;
    [self.view addSubview:cover];

    //2、调整阴影和图像顺序
    [self.view bringSubviewToFront:self.iconBtn];

    //相同。用block改造以下的代码
    [UIView animateWithDuration:0.5 animations:^{
        cover.alpha=0.7;//阴影逐步出现
        //3、改变图像大小frame
        CGFloat iconW=self.view.frame.size.width;
        CGFloat iconH=iconW;
        CGFloat iconY=(self.view.frame.size.height-iconH)/2;
        self.iconBtn.frame=CGRectMake(0, iconY, iconW, iconH);
    }];

//    [UIView beginAnimations:nil context:nil];
//    cover.alpha=0.7;//阴影逐步出现
//    //3、改变图像大小frame
//    CGFloat iconW=self.view.frame.size.width;
//    CGFloat iconH=iconW;
//    CGFloat iconY=(self.view.frame.size.height-iconH)/2;
//    self.iconBtn.frame=CGRectMake(0, iconY, iconW, iconH);
//    [UIView commitAnimations];
}

上述代码中得阴影cover有一个事件,就是点击后图片恢复小图,而且阴影消失等等。例如以下:

-(void)smallImg{
    //用block动画改造以下代码以及removeCover方法
    [UIView animateWithDuration:0.5 animations:^{
        self.cover.alpha=0;//先让阴影逐渐消失,然后删除
        self.iconBtn.frame=CGRectMake(85, 86, 150, 150);
    } completion:^(BOOL finished) {
        [self.cover removeFromSuperview];
        self.cover=nil;//便于推断阴影是否还存在
    }];

//    //1、删除阴影
//
//    //2、图像位置恢复frame
//    [UIView beginAnimations:nil context:nil];
//    //动画结束后,调用self的removeCover方法删除阴影,这样删除阴影才会有个延迟,阴影逐渐消失的动画才干正常
//    [UIView setAnimationDelegate:self];
//    [UIView setAnimationDidStopSelector:@selector(removeCover)];
//    self.cover.alpha=0;//先让阴影逐渐消失,然后删除
//    self.iconBtn.frame=CGRectMake(85, 86, 150, 150);//也能够在变大之前记录原有位置
//    [UIView commitAnimations];
}

//-(void)removeCover{
//    [self.cover removeFromSuperview];
//    self.cover=nil;//便于推断阴影是否还存在
//}

(7)而点击图片本身,也会有放大缩小的事件:

- (IBAction)iconClick {
    if (self.cover==nil) {
        [self bigImg];
    }else{
        [self smallImg];
    }
}

(8)用到的知识点

——获取button当前文字用.currentTitle属性。

——实现动画特效,除了[UIView beginAnimations:]这套组合外,推荐使用[UIView animateWithDuration: animations:^{ } completion:^(BOOL finished) { }];假设动画完毕后没有须要运行的代码。那么最后面的completion能够去除。

——调整子视图上下叠加顺序能够用bringSubviewToFront之类的方法。

——注意,button的文字默认是白色,假设背景也是白色,那么须要格外注意。

——假设图片的frame属性设置没有生效,即没有变大缩小移动等特效。那么通常是Auto Layout没有关闭。

——button有一个默认属性:按下时颜色变暗,假设不须要,则取消勾选“Highlighted Adjusts Image”。

——截取某字符串的前某几个字符则用substringToIndex。数字是N,则是0~n-1这几个字符。

——实现透明度,是属性alpha。

——一般要删除某个控件,则须要这个控件自身调用removeFromSuperview方法。

但假设要删除某个视图里面的非常多子视图,除了用for循环让子视图一个个自己自删,还能够用例如以下方法:makeObjectsPerformSelector。

    [self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
//    for (UIView *subViews in self.answerView.subviews) {
//        [subViews removeFromSuperview];
//    }

——一般我们假设删除某个控件,在删除后,把这个控件设置为nil。而不想删除。仅仅是隐藏,后面还须要再显示,则用控件的hidden属性。

——注意代码顺序。比方用button上得文字和其它button上的文字相比較,然后在删除这个button,这是正确顺序,而不能先删除,否则后面无法获取到这个button上得文字。

——推断button有没有文字:推断button文字的长度是否等于0。

——可变字符串的加入用appendString方法。

——延迟运行某个动作能够用performSelector:@selector() withObject:nil afterDelay:这种方法。

假设是[self perform...]那么就是延迟运行self的selector里的方法。

——把一个字符串转换成整型,能够直接在这个字符串后面添加.intValue属性。

(9)怎样加入icon图标(iPhone的、AppStore以及spotlight的,当然兴许还有ipad的等等)

直接按要求定义好图片大小和命名规范。然后拖到Image.xcassets的AppIcon里就可以。

(10)怎样加入启动页面?

直接在LaunchScreen.xib里面设置。这个和玩storyboard一样样的。

我们此处设置的大小是3.5inch的。所以设置好设备尺寸后。把原先的删除掉,直接弄一个imageView。在上面加入个图片就可以。

时间: 2024-08-06 00:42:02

【iOS开发-51】案例学习:动画新写法、删除子视图、视图顺序、延迟方法、button多功能使用方法及icon图标和启动页设置的相关文章

iOS开发UI篇—核心动画(基础动画)

iOS开发UI篇—核心动画(基础动画) 一.简单介绍 CAPropertyAnimation的子类 属性解析: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue 如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态.但

iOS开发UI篇—核心动画(转场动画和组动画)

iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果 属性解析: type:动画过渡类型 subtype:动画过渡方向 startProgress:动画起点(在整体动画的百分比) endProgress:动画终点(在整体动画的百分比)

iOS开发UI篇—核心动画(关键帧动画)

iOS开发UI篇—核心动画(关键帧动画) 一.简单介绍 是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值 属性解析: values:就是上述的NSArray对象.里面的元素称为”关键帧”(keyframe).动画对象会在指定的时间(duration)内,依次显示values数组

IOS开发-UI学习-sqlite数据库的操作

IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这两款著名的数据库都还快,在ios和安卓app中常用来完成对数据进行离线缓存的处理,如新闻数据的离线缓存. 它的基本操作步骤是: 1.先加入sqlite开发库libsqlite3.dylib, 2.新建或打开数据库, 3.创建数据表, 4.插入数据, 5.查询数据并打印, 6.关闭数据库, 具体操作步

iOS开发UI篇—核心动画(转场动画和组动画)(转摘)

iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果 属性解析: type:动画过渡类型 subtype:动画过渡方向 startProgress:动画起点(在整体动画的百分比) endProgress:动画终点(在整体动画的百分比)

iOS开发UI篇—核心动画(关键帧动画)(转摘)

iOS开发UI篇—核心动画(关键帧动画) 一.简单介绍 是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值 属性解析: values:就是上述的NSArray对象.里面的元素称为”关键帧”(keyframe).动画对象会在指定的时间(duration)内,依次显示values数组

iOS开发UI篇—核心动画(UIView封装动画)(转摘)

iOS开发UI篇—核心动画(UIView封装动画) 一.UIView动画(首尾) 1.简单说明 UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持 执行动画所需要的工作由UIView类自动完成,但仍要在希望执行动画时通知视图,为此需要将改变属性的代码放在[UIViewbeginAnimations:nil context:nil]和[UIView commitAnimations]之间 常见方法解析: + (void)setAnimati

IOS开发-OC学习-常用功能代码片段整理

IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是在做与URL有关的功能时,需要在Info.plist中添加一段代码进而实现让网址完成从Http到Https的转换,以及其他的一些功能. 在从一个新手到逐渐学会各种功能.代码.控件.方法如何使用的过程中,也在逐渐积累一些知识,但是一次总不会把这些东西都深刻记住并完全理解.所以在这儿记录下这些东西,用来

iOS开发UI篇—核心动画简介

iOS开发UI篇—核心动画简介 一.简单介绍 Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍.也就是说,使用少量的代码就可以实现非常强大的功能. Core Animation是跨平台的,可以用在Mac OS X和iOS平台. Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程.不阻塞主线程,可以理解为在执行动画的时候还能点击(按钮). 要注意的是,Core Animation是直接作用