标签:
1>在项目开发中产品经理会提出现在主流的界面引导这样增加用户体验感尤其在iOS开发中更加注重用户体验,那么暗文引导界面就值得学习一下;
2>本人在项目中虽然没有这样的实例需求但是自己还是模仿做了一个简单暗文引导界面供博友们采纳;
3>希望博友们在体会这个交互同时明白这个原理,废话不多说上代码,上思路;
//
// ViewController.h
// 项目-版本新特性
//
// Created by 周昭 on 16/3/29.
// Copyright ? 2016年 Jordan Zhou. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZZHomeViewController: UIViewController
@end
//
// ViewController.m
// 项目-版本新特性
//
// Created by 周昭 on 16/3/29.
// Copyright ? 2016年 Jordan Zhou. All rights reserved.
//
#import "ZZHomeViewController.h"
#import "ZZShowGuide.h"
/*
1>随意创建一些控件
2>自定义封装的暗文引导界面View
3>那么废话不多说直接上代码
*/
@interface ZZHomeViewController ()
@end
@implementation ZZHomeViewController
- (void)viewDidLoad {
[superviewDidLoad];
// 这里这么写是方便版本本地化及支持多语言
self.title =NSLocalizedString(@"ZZ_iOSDeveloper",nil);
self.view.backgroundColor = [UIColororangeColor];
// 0.设置导航栏右上角
[selfsetUpNavRightAddButton];
// 1.随意创建一些控件
[selfsetUpSomeSubViews];
// 2.显示引导界面
[selfsetUpShowGuide];
}
/**
* 暗文引导界面
*/
- (void)setUpShowGuide
{
NSUserDefaults *guideDefaults = [NSUserDefaultsstandardUserDefaults];
BOOL isShow = [guideDefaults boolForKey:@"guideIsShow"];
if (isShow) {
ZZShowGuide *showGuideView = [[ZZShowGuidealloc]initWithFrame:[UIScreenmainScreen].bounds];
[showGuideView show];
}
}
/**
* 设置导航栏右上角
*/
- (void)setUpNavRightAddButton
{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:selfaction:@selector(addInfo)];
}
/**
* 随意创建一些控件
*/
- (void)setUpSomeSubViews
{
// 1.创建一个可以点击的按钮这里可以调用系统相机\相册这个功能下期再讲解
UIButton *iconBtn = [[UIButtonalloc]init];
iconBtn.center =CGPointMake(self.view.frame.size.width * 0.5, self.view.frame.size.height *0.3);
iconBtn.bounds = CGRectMake(0, 0, 100, 100);
[iconBtn setImage:[UIImageimageNamed:@"lufy"]forState:UIControlStateNormal];
iconBtn.clipsToBounds = YES;
iconBtn.layer.masksToBounds =YES;
iconBtn.layer.cornerRadius =100 /2;
[self.viewaddSubview:iconBtn];
// 2.创建一个可以点击的按钮可以选择跳转控制器或者其它
UIButton *someBtn = [[UIButtonalloc]init];
someBtn.center =CGPointMake(self.view.frame.size.width * 0.5, self.view.frame.size.height *0.8);
someBtn.bounds = CGRectMake(0, 0, self.view.frame.size.width -100,50);
[someBtn setTitle:NSLocalizedString(@"自己去写方法",nil)forState:UIControlStateNormal];
someBtn.backgroundColor = [UIColorwhiteColor];
someBtn.layer.cornerRadius =3;
someBtn.layer.borderColor = [[UIColorgrayColor]CGColor];
someBtn.layer.masksToBounds =YES;
[self.viewaddSubview:someBtn];
}
#pragma mark --- 自己实现方法
- (void)addInfo
{
NSLog(@"下期再讲调用系统相机\\相册");
}
@end
//
// ZZShowGuide.h
// Eknot
//
// Created by 周昭 on 16/3/18.
// Copyright ? 2016年 Jordan Zhou. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZZShowGuide : UIView
/**
* 展示
*/
- (void)show;
/**
* 动画显示
*
* @param rmView 移除的View
* @param showView 显示的View
*/
- (void)removeView:(UIView *)rmView showView:(UIView *)showView;
@end
//
// ZZShowGuide.m
// Eknot
//
// Created by 周昭 on 16/3/18.
// Copyright ? 2016年 Jordan Zhou. All rights reserved.
//
#import "ZZShowGuide.h"
#import "ZZDrawView.h"
@interface ZZShowGuide()
/**
* 背景view
*/
@property (nonatomic,weak)UIView *bgView;
/**
* 显示的view
*/
@property (nonatomic,weak)ZZDrawView *contentView;
/**
* 添加的文字描述
*/
@property (nonatomic,weak)UILabel *addBabyLabel;
@property (nonatomic,weak)UILabel *choosePicLabel;
@property (nonatomic,weak)UILabel *publicSearchLabel;
/**
* 装载view的数组
*/
@property (nonatomic,strong)NSMutableArray *allViewsArray;
/**
* 标记index
*/
@property (nonatomic,assign)NSInteger index;
@end
@implementation ZZShowGuide
/**
* 懒加载\这样我们就不需要去管这个数组是什么时候创建
*/
- (NSMutableArray *)allViewsArray
{
if (!_allViewsArray) {
_allViewsArray = [NSMutableArrayarray];
}
return_allViewsArray;
}
/**
* 点击弹出框以外的部分,则收起当前弹出框对应的View
*
* @param gestureRecognizer UITapGestureRecognizer
*/
- (void)triggerTapGesture:(UITapGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state ==UIGestureRecognizerStateEnded) {
// 展示一个\销毁一个通过index和数组的顺序来标识
#pragma mark --- 这里这些if else if这样的垃圾代码我们是不是应该屏蔽封装起来?那么同学们自己去尝试在方法在传出index这个参数并且也可以自己完美的实现动画的效果
[selfremoveView:self.allViewsArray[_index]showView:self.allViewsArray[_index +1]];
if (_index ==0) {
#warning ----- 在这里我们传出的这些点?同学们是不是看的很蛋疼?我自己也觉得很蛋疼!那么请问怎么做?
// 1.我们是不是在自己的项目中显示在主界面上面的view也应该自定义?
// 2.这个view我们是不是应该提供它的数据模型和frame模型?
// 3.那么我们在这个自定义的view中加载这个模型拿到模型去取模型中的每个值就够了?
// 4.我内部怎么设置关你屁事?这样把细节的操作屏蔽起来,这才叫做MVC大家体会到这个好处没有?
[self.contentViewreDrawLineBeginPoint:CGPointMake(self.choosePicLabel.center.x,self.choosePicLabel.center.y -10) endPoint:CGPointMake(self.frame.size.width * 0.5 - 43,self.frame.size.height *0.3 + 30) upPoint:CGPointMake(self.frame.size.width *0.5 - 48,self.frame.size.height *0.3 +27) downPoint:CGPointMake(self.frame.size.width *0.5 - 42.8,self.frame.size.height *0.3 + 35.5)lineWidth:2lineColor:[UIColorgreenColor]];
} else if (_index ==1) {
[self.contentViewreDrawLineBeginPoint:CGPointMake(self.publicSearchLabel.center.x,self.publicSearchLabel.center.y +10) endPoint:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height *0.8 - 27) upPoint:CGPointMake(self.frame.size.width * 0.5 + 3, self.frame.size.height * 0.8 - 33) downPoint:CGPointMake(self.frame.size.width * 0.5 + 5.5, self.frame.size.height * 0.8 - 24) lineWidth:2lineColor:[UIColorgreenColor]];
} else if (_index ==2) {//特殊处理
[UIViewanimateWithDuration:0.5animations:^{
[selfremoveFromSuperview];//这里会添加一层所以要特别处理\不然主线程会卡死
}];
}
_index++;
}
}
/**
* 初始化
*/
- (id)initWithFrame:(CGRect)frame
{
if (self = [superinitWithFrame:frame]) {
self.backgroundColor = [UIColorclearColor];
// 背景
UIView *bgView = [[UIViewalloc]initWithFrame:self.bounds];
bgView.backgroundColor = [UIColorblackColor];
bgView.alpha = 0.7;
[self addSubview:bgView];
self.bgView = bgView;
#warning ---- 这里我们已经设置了一个背景那么为什么我们又要在添加一层自定义的ZZDrawView呢?那么请问同学们这是为什么?当然这个view中也会自动实现drawRect方法但是你设置了alpha那么请问你的字控件怎么添加你这不是傻逼吗?当然这样我们的业务逻辑也分的更加清楚!
// 添加Label的View起到分离隔层的效果
ZZDrawView *contentView = [[ZZDrawViewalloc]initWithFrame:self.bounds];
contentView.backgroundColor = [UIColorclearColor];
[self addSubview:contentView];
self.contentView = contentView;
// 点击添加宝贝
UILabel *addBabyLabel = [[UILabelalloc]init];
addBabyLabel.text = NSLocalizedString(@"点击添加",nil);
addBabyLabel.textColor = [UIColorwhiteColor];
addBabyLabel.textAlignment = NSTextAlignmentCenter;
CGFloat addBabyLabelX = self.frame.size.width *0.5;
CGFloat addBabyLabelY = self.frame.size.height *0.12;
CGFloat addBabyLabelW = self.frame.size.width - addBabyLabelX;
CGFloat addBabyLabelH = 20;
addBabyLabel.frame = CGRectMake(addBabyLabelX, addBabyLabelY, addBabyLabelW, addBabyLabelH);
[contentView addSubview:addBabyLabel];
self.addBabyLabel = addBabyLabel;
// 刚开始显示的时候就有一条线所以设置一次
[contentView reDrawLineBeginPoint:CGPointMake(addBabyLabel.center.x, addBabyLabelY)endPoint:CGPointMake(self.frame.size.width -35, 45) upPoint:CGPointMake(self.frame.size.width -40,43)downPoint:CGPointMake(self.frame.size.width -37,50) lineWidth:2lineColor:[UIColorgreenColor]];
// 点击拍照
UILabel *choosePicLabel = [[UILabelalloc]init];
choosePicLabel.text = NSLocalizedString(@"点击设置图片",nil);
choosePicLabel.textColor = [UIColorwhiteColor];
choosePicLabel.textAlignment = NSTextAlignmentCenter;
choosePicLabel.alpha = 0.0f;
CGFloat choosePicLabelX = self.frame.size.width *0.03;
CGFloat choosePicLabelY = self.frame.size.height *0.4;
CGFloat choosePicLabelW = 130;
CGFloat choosePicLabelH = 20;
choosePicLabel.frame = CGRectMake(choosePicLabelX, choosePicLabelY, choosePicLabelW, choosePicLabelH);
[contentView addSubview:choosePicLabel];
self.choosePicLabel = choosePicLabel;
// 点击开启自己的功能
UILabel *publicSearchLabel = [[UILabelalloc]init];
publicSearchLabel.text = NSLocalizedString(@"点击开启自己的功能",nil);
publicSearchLabel.textColor = [UIColorwhiteColor];
publicSearchLabel.textAlignment = NSTextAlignmentCenter;
publicSearchLabel.alpha = 0.0f;
CGFloat publicSearchLabelX = addBabyLabelX -50;
CGFloat publicSearchLabelY = self.frame.size.height -210;
CGFloat publicSearchLabelW = self.frame.size.width - publicSearchLabelX;
CGFloat publicSearchLabelH = 20;
publicSearchLabel.frame = CGRectMake(publicSearchLabelX, publicSearchLabelY, publicSearchLabelW, publicSearchLabelH);
[contentView addSubview:publicSearchLabel];
self.publicSearchLabel = publicSearchLabel;
#pragma mark ---- 这里同学们一定要注意数组是有序的所以要注意添加的顺序
[self.allViewsArrayaddObject:addBabyLabel];
[self.allViewsArrayaddObject:choosePicLabel];
[self.allViewsArrayaddObject:publicSearchLabel];
[self.allViewsArrayaddObject:contentView];
[self.allViewsArrayaddObject:bgView];
// 那么请问这里为什么是contentView 添加手势而不是别的?
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(triggerTapGesture:)];
[contentView addGestureRecognizer:tapGesture];
}
return self;
}
/**
* 添加
*/
- (void)show
{
UIWindow *appWindow = [[[UIApplicationsharedApplication]delegate]window];
[appWindow addSubview:self];
// 归档已经展示
BOOL isShow = YES;
NSUserDefaults *guideDefaults = [NSUserDefaultsstandardUserDefaults];
[guideDefaults setBool:isShow forKey:@"guideIsShow"];
[guideDefaults synchronize];
}
/**
* 动态移除添加方法
*/
- (void)removeView:(UIView *)rmView showView:(UIView *)showView
{
[UIViewanimateWithDuration:0.3animations:^{
[rmView removeFromSuperview];
} completion:^(BOOL finished) {
[UIViewanimateWithDuration:0.5animations:^{
showView.alpha = 1.0f;
}];
}];
}
#pragma mark --- 那么这里留一个问题同学可以自己先想一下!一般箭头所的那些能点或者增加的功能控件我们是不是应该让他们亮起来?那么请问做?
- (void)drawRect:(CGRect)rect
{
// 提示
// 1.在这个方法中去实现
// 2.大家可以去细细的想一下缕一下这个层次关系
}
@end
//
// ZZDrawView.h
// 项目-版本新特性
//
// Created by 周昭 on 16/3/30.
// Copyright ? 2016年 Jordan Zhou. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZZDrawView : UIView
Simulator Screen Shot 2016年3月31日 下午6.09.56.png
/**
* 起点
*/
@property (nonatomic,assign)CGPoint beginPoint;
/**
* 止点
*/
@property (nonatomic,assign)CGPoint endPoint;
/**
* 上转点
*/
@property (nonatomic,assign)CGPoint upPoint;
/**
* 下转点
*/
@property (nonatomic,assign)CGPoint downPoint;
/**
* 线宽
*/
@property (nonatomic,assign)CGFloat lineWidth;
/**
* 线的颜色
*/
@property (nonatomic,weak)UIColor *lineColor;
/**
* 在这里我们是不是应该提供一个接口出来让别人来设置这些属性?那么我觉得这是不彻底的我们是不是应该封装一个ZZDrawView的Model模型来赋值这些值?
*
* @param beginPoint 起点
* @param endPoint 终点
* @param upPoint 上转折点
* @param downPoint 下转折点
* @param lineWidth 线宽
* @param lineColor 线的颜色
*/
- (void)reDrawLineBeginPoint:(CGPoint)beginPoint endPoint:(CGPoint)endPoint upPoint:(CGPoint)upPoint downPoint:(CGPoint)downPoint lineWidth:(CGFloat)lineWidth lineColor:(UIColor *)lineColor;
@end
//
// ZZDrawView.m
// 项目-版本新特性
//
// Created by 周昭 on 16/3/30.
// Copyright ? 2016年 Jordan Zhou. All rights reserved.
//
#import "ZZDrawView.h"
@implementation ZZDrawView
/**
* 重写set方法(那么同学们为什么要在这里调用[self setNeedsDisplay]?) 这样不就把细节屏蔽在内部?体会到这个好处没有?
*
* @param beginPoint 起点
* @param endPoint 终点
* @param upPoint 上转折点
* @param downPoint 下转折点
* @param lineWidth 线宽
* @param lineColor 线的颜色
*/
- (void)reDrawLineBeginPoint:(CGPoint)beginPoint endPoint:(CGPoint)endPoint upPoint:(CGPoint)upPoint downPoint:(CGPoint)downPoint lineWidth:(CGFloat)lineWidth lineColor:(UIColor *)lineColor
{
self.beginPoint = beginPoint;
self.endPoint = endPoint;
self.upPoint = upPoint;
self.downPoint = downPoint;
self.lineWidth = lineWidth;
self.lineColor = lineColor;
#warning 这个是系统的方法所以只能是自己调用不能你手动去调用这个方法!
[selfsetNeedsDisplay];
}
#pragma mark --- 那么这里讲到绘图本期暗文我采用的最基本点与点之间连线实现\下期再给同学们分享我个人非常喜欢的 Quartz2D
/**
* 当你的view加载的时候drawRect方法只会调一次
*/
- (void)drawRect:(CGRect)rect
{
// NSLog(@"drawRect-------"); 同学们自己去验证一下
// 1.获得图形上下文
CGContextRef ctx =UIGraphicsGetCurrentContext();
// 2.设置ctx的属性
// 设置线宽
CGContextSetLineWidth(ctx,self.lineWidth);
// 设置颜色
[self.lineColorset]; // [[UIColor redColor] set];
// 设置线段头尾部的样式
CGContextSetLineCap(ctx,kCGLineCapRound);
/**第一条线连接线**/
// 创建一个起点
CGContextMoveToPoint(ctx,self.beginPoint.x,self.beginPoint.y);
// 连接到终点
CGContextAddLineToPoint(ctx,self.endPoint.x,self.endPoint.y);
/**第二条线上转角**/
CGContextMoveToPoint(ctx,self.upPoint.x,self.upPoint.y);
CGContextAddLineToPoint(ctx,self.endPoint.x,self.endPoint.y);
/**第三条线下转角**/
CGContextMoveToPoint(ctx,self.downPoint.x,self.downPoint.y);
CGContextAddLineToPoint(ctx,self.endPoint.x,self.endPoint.y);
// 3.绘制
CGContextStrokePath(ctx);
}
@end
@end
标签:
原文地址:http://blog.csdn.net/zz_iosdeveloper/article/details/51007980