UI设计给出了设计图,界面却是不错,看着霸气十足,可是里面的控件,都需要自定义,没有一个不需要折腾的,也罢,就一直在折腾了。折腾中遇到一个问题,UISlder的完全自定义,完全摒弃原生态的东西,开始有点无厘头,慢慢页折腾出来了,今天给出一些关键代码和demo,只是简单的实现,很多功能有待发掘。
首先看一下UI给出的效果图:
网上有一种自定义UISlider的方法,但是最后放弃了,因为依然没有达到所需,也是比人才疏学浅。
下面就是我自定义的类UISlider的部分代码:
1、首先我声明了一个继承子UIView的类,因为我觉的使用UIView页绘制更加快捷。
//
// Slider.h
// SliderPro
//
// Created by Yongchao Zhang on 12-9-13.
// Copyright (c) 2012年 Yongchao Zhang. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol SliderDelegate;
@interface Slider : UIView{
//放置时间
UIImageView *popView;
//箭头
UIImageView *tagView;
UILabel *currentLabel;
UILabel *totalLabel;
NSString *currentStr;
NSString *totalStr;
float minValue, maxValue;
float currentValue;
float percent;
UIImageView *bottomView;
UIImageView *topView;
}
@property (nonatomic,readwrite) float minValue, maxValue, currentValue;
@property (nonatomic,strong) UILabel *currentLabel,*totalLabel;
@property (nonatomic,strong) NSString *currentStr,*totalStr;
@property (nonatomic,unsafe_unretained)id<SliderDelegate> delegate;
@end
@protocol SliderDelegate <NSObject>
-(void)scrollBegin:(Slider *)sender;
-(void)scroll:(Slider *)sender;
-(void)scrollDone:(Slider*)sender;
@end
2、在实现的时候,需要掌握三种情况的计算,最左边、最右边、中间位置。因为那个小箭头是需要实时的移动的,不同的位置小箭头的上面所谓的时间view移动的不同。
//
// Slider.m
// SliderPro
//
// Created by Yongchao Zhang on 12-9-13.
// Copyright (c) 2012年 Yongchao Zhang. All rights reserved.
//
#import "Slider.h"
#import <QuartzCore/QuartzCore.h>
@implementation Slider
@synthesize currentValue,maxValue,minValue;
@synthesize currentLabel,totalLabel;
@synthesize currentStr,totalStr;
@synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
minValue = 0;
maxValue = 1;
currentValue = 0;
self.backgroundColor = [UIColor redColor];
self.userInteractionEnabled = YES;
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
//上半部分整体
popView= [[UIImageView alloc] init];
popView.userInteractionEnabled = NO;
// [popView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"timeBack.png"]]];
[popView setImage:[UIImage imageNamed:@"timeBack.png"]];
[self addSubview:popView];
//时间部分
UIView *timeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, popView.frame.size.width, self.frame.size.height/2 - 20)];
[timeView setBackgroundColor:[UIColor greenColor]];
currentLabel = [[UILabel alloc]init];
[currentLabel setBackgroundColor:[UIColor blackColor]];
[currentLabel setTextColor:[UIColor whiteColor]];
[currentLabel setTextAlignment:UITextAlignmentLeft];
[timeView addSubview:currentLabel];
totalLabel = [[UILabel alloc]init];
[totalLabel setBackgroundColor:[UIColor greenColor]];
// [totalLabel setTextColor:UIColorFromRGB(0x73736f)];
[totalLabel setTextColor:[UIColor redColor]];
[totalLabel setTextAlignment:UITextAlignmentLeft];
[timeView addSubview:totalLabel];
[popView addSubview:timeView];
//箭头部分
tagView = [[UIImageView alloc] init];
tagView.userInteractionEnabled = NO;
// [tagView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"tag.png"]]];
[tagView setImage:[UIImage imageNamed:@"tag.png"]];
[self addSubview:tagView];
//下半部分
UIImage *stetchLeftTrack = [UIImage imageNamed:@"done.png"] ;
UIImage *stetchRightTrack = [UIImage imageNamed:@"max.png"] ;
bottomView= [[UIImageView alloc] initWithImage:stetchRightTrack];
[bottomView setFrame:CGRectMake(5, popView.frame.origin.y + popView.frame.size.height + tagView.frame.size.height+20 , self.frame.size.width-10, 6)];
CALayer *layers = [bottomView layer];
[layers setMasksToBounds:YES];
[layers setCornerRadius:4.0];
topView= [[UIImageView alloc] initWithImage:stetchLeftTrack];
[topView setFrame:CGRectMake(0, 0 , self.frame.size.width-10, 6)];
[bottomView addSubview:topView];
[self addSubview:bottomView];
}
-(void)layoutSubviews{
[popView setFrame:CGRectMake(0, 0, 72, self.frame.size.height/2-18)];
[tagView setFrame:CGRectMake(0, popView.frame.origin.y + popView.frame.size.height-1, 6, 3)];
[currentLabel setFrame:CGRectMake(4, 2.0f, 30, 10)];
currentLabel.font=[UIFont systemFontOfSize:7.0f];
[totalLabel setFrame:CGRectMake(38, 2.0f, 30, 10)];
totalLabel.font=[UIFont systemFontOfSize:7.0f];
currentLabel.text = currentStr;
totalLabel.text = totalStr;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch* touch = [touches anyObject];
CGPoint xy = [touch locationInView:self];
float pointX = xy.x-bottomView.frame.origin.x;
if(pointX<0)
pointX =0;
if(pointX > bottomView.frame.size.width)
pointX = bottomView.frame.size.width;
percent = pointX / bottomView.frame.size.width;
currentValue = percent *maxValue;
[self updateProView:pointX];
[self.delegate scrollBegin:self];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch* touch = [touches anyObject];
CGPoint xy = [touch locationInView:self];
float pointX = xy.x-bottomView.frame.origin.x;
if(pointX<0)
pointX =0;
if(pointX > bottomView.frame.size.width)
pointX = bottomView.frame.size.width;
percent = pointX / bottomView.frame.size.width;
currentValue = percent *maxValue;
[self updateProView:pointX];
[self.delegate scroll:self];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch* touch = [touches anyObject];
CGPoint xy = [touch locationInView:self];
float pointX = xy.x-bottomView.frame.origin.x;
if(pointX<0)
pointX =0;
if(pointX > bottomView.frame.size.width)
pointX = bottomView.frame.size.width;
percent = pointX / bottomView.frame.size.width;
currentValue = percent *maxValue;
[self updateProView:pointX];
[self.delegate scrollDone:self];
}
-(void)updateProView:(float)_pointx{
CGRect rect = topView.frame;
rect.size.width = _pointx;
topView.frame = rect;
float realX = _pointx + bottomView.frame.origin.x;
CGRect popRect = popView.frame;
popRect.origin.x = realX-popRect.size.width/2;
if(realX < popRect.size.width/2){
popRect.origin.x = 0;
}
if(realX >self.frame.size.width - popRect.size.width/2){
popRect.origin.x = self .frame.size.width - popRect.size.width;
}
CGRect sanRect = tagView.frame;
sanRect.origin.x = realX - sanRect.size.width/2;
if(sanRect.origin.x < (bottomView.frame.origin.x - sanRect.size.width/2) )
sanRect.origin.x = bottomView.frame.origin.x - sanRect.size.width/2;
if(sanRect.origin.x > (bottomView.frame.origin.x +bottomView.frame.size.width - sanRect.size.width/2))
sanRect.origin.x = bottomView.frame.origin.x +bottomView.frame.size.width - sanRect.size.width/2;
tagView.frame = sanRect;
popView.frame = popRect;
}
-(void)setMinValue:(float)_minValue{
minValue = _minValue;
}
-(void)setMaxValue:(float)_maxValue{
maxValue = _maxValue;
}
-(void)setCurrentValue:(float)_value{
currentValue = _value;
percent = currentValue /maxValue;
float pointX = percent * bottomView.frame.size.width;
[self updateProView:pointX];
}
@end
注:代码比较乱,也难免有错误,毕竟只是为了验证思路而已。