描述:模仿开源组建完成的一个滑动解锁控件
效果如图:
思路如下:
1.重写redraw 绘制背景(2个圆圈)以及控件slider。
2.为slider新增panGesture 从而实现拖动效果。
3.gesture的相应函数根据不同情况回调delegate完成自定义状态修改。
注意:
1.redraw默认背景是黑色,需要改为白色。
2.之前对@property 的assign 不是很熟悉这次有新的了解,这个使用在常量上如此次使用在CGFloat上,此时在.m仅实现属性的get方法是不会被提示需要实现set方法的。
3.CGRectGet****系列的用法
4.min() max() pow() sqrt()的熟悉
待改善:
1.可以设置slider-图片大小等
2.可以设置背景的2个圈圈的大小以及可以选择填充。
代码:
//
// PLLSlideToUnlock.h
// SlideToUnlock
//
// Created by liu poolo on 14-7-28.
// Copyright (c) 2014年 liu poolo. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol PLLSlideToUnlockDelegate <NSObject>
@required
-(void)beginPanning;
-(void)statusChangeLock;
-(void)statusChangeUnLock;
-(void)doLock;
-(void)doUnlock;
-(void)endPanning;
@end
@interface PLLSlideToUnlock : UIView
@property (nonatomic,assign) CGFloat raidusInside;
@property (nonatomic,assign) CGFloat raidusOutside;
@property id<PLLSlideToUnlockDelegate> delegate;
@end
//
// PLLSlideToUnlock.m
// SlideToUnlock
//
// Created by liu poolo on 14-7-28.
// Copyright (c) 2014年 liu poolo. All rights reserved.
//
#import "PLLSlideToUnlock.h"
const static CGFloat default_raidus = 25.0f;
@interface PLLSlideToUnlock(){
BOOL _statusLocked;
}
@property (nonatomic, strong) UIView* slider;
@end
@implementation PLLSlideToUnlock
-(CGFloat)raidusInside{
return _raidusInside?:default_raidus;
}
-(CGFloat)raidusOutside{
if(_raidusInside){
return _raidusInside;
}
CGFloat height=CGRectGetHeight(self.bounds);
CGFloat width=CGRectGetWidth(self.bounds);
return MIN(height, width)/2;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
_statusLocked=YES;
[self setBackgroundColor:[UIColor clearColor]];
if (self) {
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[self drawRaidus:self.raidusInside withColor:[UIColor blueColor]];
[self drawRaidus:self.raidusOutside withColor:[UIColor greenColor]];
[self addButtonAtCenter];
[self addPingesture];
}
- (void)drawRaidus:(NSInteger)radius withColor:(UIColor*)color
{
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, color.CGColor);
CGRect rect=CGRectMake(self.center.x-radius, self.center.y-radius, radius*2, radius*2);
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
}
- (void)addButtonAtCenter{
self.slider = [[UIView alloc] initWithFrame:CGRectMake(self.center.x, self.center.y, self.raidusInside*2, self.raidusInside*2)];
self.slider.clipsToBounds=YES;
self.slider.layer.cornerRadius=self.raidusInside;
[self.slider setBackgroundColor:[UIColor redColor]];
[self addSubview:self.slider];
self.slider.center=self.center;
}
-(void)addPingesture{
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
[self.slider addGestureRecognizer:panGesture];
}
-(void)handlePan:(UIPanGestureRecognizer*)pan{
if (pan.state==UIGestureRecognizerStateBegan) {
if([self.delegate respondsToSelector:@selector(beginPanning)]){
[self.delegate beginPanning];
}
}else if (pan.state==UIGestureRecognizerStateChanged) {
CGPoint trasnlationPoint=[pan translationInView:pan.view];
self.slider.center=CGPointMake(self.center.x+trasnlationPoint.x, self.center.y+trasnlationPoint.y);
if(sqrt(pow(trasnlationPoint.x, 2)+pow(trasnlationPoint.y, 2))>(self.raidusInside+self.raidusOutside)){
if(_statusLocked){
if([self.delegate respondsToSelector:@selector(statusChangeUnLock)]){
//解锁
_statusLocked=NO;
[self.delegate statusChangeUnLock];
}
}
}else{
if(!_statusLocked&&!_statusLocked){
if([self.delegate respondsToSelector:@selector(statusChangeLock)]){
//解锁
_statusLocked=YES;
[self.delegate statusChangeLock];
}
}
}
}else if (pan.state==UIGestureRecognizerStateEnded) {
if(_statusLocked){
if([self.delegate respondsToSelector:@selector(doLock)]){
//执行锁屏操作
_statusLocked=NO;
[self.delegate doLock];
}
}else{
if([self.delegate respondsToSelector:@selector(doUnlock)]){
//执行解锁操作
_statusLocked=NO;
[self.delegate doUnlock];
}
}
[UIView animateWithDuration:0.2f animations:^{
self.slider.center=self.center;
}];
}
}
@end
效果如图:
思路如下:
1.重写redraw 绘制背景(2个圆圈)以及控件slider。
2.为slider新增panGesture 从而实现拖动效果。
3.gesture的相应函数根据不同情况回调delegate完成自定义状态修改。
注意:
1.redraw默认背景是黑色,需要改为白色。
2.之前对@property 的assign 不是很熟悉这次有新的了解,这个使用在常量上如此次使用在CGFloat上,此时在.m仅实现属性的get方法是不会被提示需要实现set方法的。
3.CGRectGet****系列的用法
4.min() max() pow() sqrt()的熟悉
待改善:
1.可以设置slider-图片大小等
2.可以设置背景的2个圈圈的大小以及可以选择填充。
代码:
//
// PLLSlideToUnlock.h
// SlideToUnlock
//
// Created by liu poolo on 14-7-28.
// Copyright (c) 2014年 liu poolo. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol PLLSlideToUnlockDelegate <NSObject>
@required
-(void)beginPanning;
-(void)statusChangeLock;
-(void)statusChangeUnLock;
-(void)doLock;
-(void)doUnlock;
-(void)endPanning;
@end
@interface PLLSlideToUnlock : UIView
@property (nonatomic,assign) CGFloat raidusInside;
@property (nonatomic,assign) CGFloat raidusOutside;
@property id<PLLSlideToUnlockDelegate> delegate;
@end
//
// PLLSlideToUnlock.m
// SlideToUnlock
//
// Created by liu poolo on 14-7-28.
// Copyright (c) 2014年 liu poolo. All rights reserved.
//
#import "PLLSlideToUnlock.h"
const static CGFloat default_raidus = 25.0f;
@interface PLLSlideToUnlock(){
BOOL _statusLocked;
}
@property (nonatomic, strong) UIView* slider;
@end
@implementation PLLSlideToUnlock
-(CGFloat)raidusInside{
return _raidusInside?:default_raidus;
}
-(CGFloat)raidusOutside{
if(_raidusInside){
return _raidusInside;
}
CGFloat height=CGRectGetHeight(self.bounds);
CGFloat width=CGRectGetWidth(self.bounds);
return MIN(height, width)/2;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
_statusLocked=YES;
[self setBackgroundColor:[UIColor clearColor]];
if (self) {
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[self drawRaidus:self.raidusInside withColor:[UIColor blueColor]];
[self drawRaidus:self.raidusOutside withColor:[UIColor greenColor]];
[self addButtonAtCenter];
[self addPingesture];
}
- (void)drawRaidus:(NSInteger)radius withColor:(UIColor*)color
{
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, color.CGColor);
CGRect rect=CGRectMake(self.center.x-radius, self.center.y-radius, radius*2, radius*2);
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
}
- (void)addButtonAtCenter{
self.slider = [[UIView alloc] initWithFrame:CGRectMake(self.center.x, self.center.y, self.raidusInside*2, self.raidusInside*2)];
self.slider.clipsToBounds=YES;
self.slider.layer.cornerRadius=self.raidusInside;
[self.slider setBackgroundColor:[UIColor redColor]];
[self addSubview:self.slider];
self.slider.center=self.center;
}
-(void)addPingesture{
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
[self.slider addGestureRecognizer:panGesture];
}
-(void)handlePan:(UIPanGestureRecognizer*)pan{
if (pan.state==UIGestureRecognizerStateBegan) {
if([self.delegate respondsToSelector:@selector(beginPanning)]){
[self.delegate beginPanning];
}
}else if (pan.state==UIGestureRecognizerStateChanged) {
CGPoint trasnlationPoint=[pan translationInView:pan.view];
self.slider.center=CGPointMake(self.center.x+trasnlationPoint.x, self.center.y+trasnlationPoint.y);
if(sqrt(pow(trasnlationPoint.x, 2)+pow(trasnlationPoint.y, 2))>(self.raidusInside+self.raidusOutside)){
if(_statusLocked){
if([self.delegate respondsToSelector:@selector(statusChangeUnLock)]){
//解锁
_statusLocked=NO;
[self.delegate statusChangeUnLock];
}
}
}else{
if(!_statusLocked&&!_statusLocked){
if([self.delegate respondsToSelector:@selector(statusChangeLock)]){
//解锁
_statusLocked=YES;
[self.delegate statusChangeLock];
}
}
}
}else if (pan.state==UIGestureRecognizerStateEnded) {
if(_statusLocked){
if([self.delegate respondsToSelector:@selector(doLock)]){
//执行锁屏操作
_statusLocked=NO;
[self.delegate doLock];
}
}else{
if([self.delegate respondsToSelector:@selector(doUnlock)]){
//执行解锁操作
_statusLocked=NO;
[self.delegate doUnlock];
}
}
[UIView animateWithDuration:0.2f animations:^{
self.slider.center=self.center;
}];
}
}
@end