与ProgressView相结合的UISlider
有一个苹果公司的方式来获得一个ProgressView的UISlider。 这是许多stream应用程序,例如本地quicktimeplayer或youtube使用。 (可以肯定的是,我只对可视化感兴趣)
欢呼西蒙
这是你所描述的一个简单的版本。
这是“简单的”,因为我不打算添加阴影和其他微妙的东西。 但是很容易构build,如果你喜欢,你可以调整它以更微妙的方式绘制。 例如,您可以制作自己的图像,并将其用作滑块的拇指。
这实际上是一个UISlider子类,位于绘制温度计的UIView子类(MyTherm)的顶部,以及绘制数字的两个UILabel。
UISlider子类消除了内置的轨道,使得它后面的温度计显示出来。 但是UISlider的拇指(旋钮)仍然可以以正常方式拖动,您可以将其设置为自定义图像,在用户拖动时获取Value Changed事件,等等。 这里是UISlider子类的代码,它消除了自己的轨迹:
- (CGRect)trackRectForBounds:(CGRect)bounds { CGRect result = [super trackRectForBounds:bounds]; result.size.height = 0; return result; }
温度计是自定义UIView子类MyTherm的一个实例。 我在笔尖实例化它,取消选中它的不透明,并给它一个清除颜色的背景颜色。 它有一个value
财产,所以它知道多less钱来填写温度计。 这是它的drawRect:
代码:
- (void)drawRect:(CGRect)rect { CGContextRef c = UIGraphicsGetCurrentContext(); [[UIColor whiteColor] set]; CGFloat ins = 2.0; CGRect r = CGRectInset(self.bounds, ins, ins); CGFloat radius = r.size.height / 2.0; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, CGRectGetMaxX(r) - radius, ins); CGPathAddArc(path, NULL, radius+ins, radius+ins, radius, -M_PI/2.0, M_PI/2.0, true); CGPathAddArc(path, NULL, CGRectGetMaxX(r) - radius, radius+ins, radius, M_PI/2.0, -M_PI/2.0, true); CGPathCloseSubpath(path); CGContextAddPath(c, path); CGContextSetLineWidth(c, 2); CGContextStrokePath(c); CGContextAddPath(c, path); CGContextClip(c); CGContextFillRect(c, CGRectMake(r.origin.x, r.origin.y, r.size.width * self.value, r.size.height)); }
要更改温度计值,请将MyTherm实例的value
更改为介于0和1之间的数字,并告诉它使用setNeedsDisplay
重绘本身。
这是可以使用标准的控制。
在界面生成器中,将您的UISlider
立即置于UISlider
之上,并使其尺寸相同。
在UISlider
,背景水平线被称为轨道,诀窍是使其不可见。 我们用透明的PNG和UISlider
方法setMinimumTrackImage:forState:
和setMaximumTrackImage:forState:
做到这一点。
在视图控制器的viewDidLoad
方法中添加:
[self.slider setMinimumTrackImage:[UIImage imageNamed:@"transparent.png"] forState:UIControlStateNormal]; [self.slider setMaximumTrackImage:[UIImage imageNamed:@"transparent.png"] forState:UIControlStateNormal];
self.slider
指的是你的UISlider
。
我已经testing了Xcode中的代码,这会给你一个独立的进度条滑块。
创build一个UISlider:
// 1 // Make the slider as a public propriety so you can access it playerSlider = [[UISlider alloc] init]; [playerSlider setContinuous:YES]; [playerSlider setHighlighted:YES]; // remove the slider filling default blue color [playerSlider setMaximumTrackTintColor:[UIColor clearColor]]; [playerSlider setMinimumTrackTintColor:[UIColor clearColor]]; // Chose your frame playerSlider.frame = CGRectMake(--- , -- , yourSliderWith , ----); // 2 // create a UIView that u can access and make it the shadow of your slider shadowSlider = [[UIView alloc] init]; shadowSlider.backgroundColor = [UIColor lightTextColor]; shadowSlider.frame = CGRectMake(playerSlider.frame.origin.x , playerSlider.frame.origin.y , playerSlider.frame.size.width , playerSlider.frame.origin.size.height); shadowSlider.layer.cornerRadius = 4; shadowSlider.layer.masksToBounds = YES; [playerSlider addSubview:shadowSlider]; [playerSlider sendSubviewToBack:shadowSlider]; // 3 // Add a timer Update your slider and shadow slider programatically [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES]; -(void)updateSlider { // Update the slider about the music time playerSlider.value = audioPlayer.currentTime; // based on ur case playerSlider.maximumValue = audioPlayer.duration; float smartWidth = 0.0; smartWidth = (yourSliderFullWidth * audioPlayer.duration ) / 100; shadowSlider.frame = CGRectMake( shadowSlider.frame.origin.x , shadowSlider.frame.origin.y , smartWidth , shadowSlider.frame.size.height); }
请享用! PS我可能有一些错别字。
适合我的devise的解决scheme:
class SliderBuffering:UISlider { let bufferProgress = UIProgressView(progressViewStyle: .Default) override init (frame : CGRect) { super.init(frame : frame) } convenience init () { self.init(frame:CGRect.zero) setup() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } func setup() { self.minimumTrackTintColor = UIColor.clearColor() self.maximumTrackTintColor = UIColor.clearColor() bufferProgress.backgroundColor = UIColor.clearColor() bufferProgress.userInteractionEnabled = false bufferProgress.progress = 0.0 bufferProgress.progressTintColor = UIColor.lightGrayColor().colorWithAlphaComponent(0.5) bufferProgress.trackTintColor = UIColor.blackColor().colorWithAlphaComponent(0.5) self.addSubview(bufferProgress) } }
想法1:你可以很容易地使用UISlider作为进度视图的子类化。 它响应诸如“setValue:animated:”之类的方法,您可以使用该方法设置视图的值(即:进度)。
你的唯一“限制”就是创build你在示例中看到的缓冲区,你可以通过“创造性地”为UISlider蒙皮(因为你可以添加自定义的皮肤)创build缓冲区,也可以通过程序设置皮肤。
想法2:另一个(更简单)选项是子类UIProgressView,并在该子类内创build一个UISlider。 你可以使UISlider的皮肤具有一个透明的皮肤(没有酒吧,只有旋钮可见),并将其放在UIProgressView上。
您可以使用UIProgressView进行预加载(缓冲),并使用UISlider进行电影控制/进度指示。
看起来相当简单:-)
编辑:要真正回答你的问题,没有内部的方式,但是用给定的工具很容易完成。
你可以这样做一些技巧,这更容易理解。 只需将代码插入UISlider子类中即可。
- (void)layoutSubviews { [super layoutSubviews]; if (_availableDurationImageView == nil) { // step 1 // get max length that our "availableDurationImageView" will show UIView *maxTrackView = [self.subviews objectAtIndex:self.subviews.count - 3]; UIImageView *maxTrackImageView = [maxTrackView.subviews objectAtIndex:0]; _maxLength = maxTrackImageView.width; // step 2 // get the right frame where our "availableDurationImageView" will place in superView UIView *minTrackView = [self.subviews objectAtIndex:self.subviews.count - 2]; _availableDurationImageView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"MediaSlider.bundle/4_jindu_huancun.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 2, 0, 2)]]; _availableDurationImageView.opaque = NO; _availableDurationImageView.frame = minTrackView.frame; [self insertSubview:_availableDurationImageView belowSubview:minTrackView]; } } - (void)setAvailableValue:(NSTimeInterval)availableValue { if (availableValue >=0 && availableValue <= 1) { // use "maxLength" and percentage to set our "availableDurationImageView" 's length _availableDurationImageView.width = _maxLength * availableValue; } }
添加亚光的解决scheme,请注意,截至iOS 7.0,实现trackRectForBounds:是不可能的。 这是我解决这个问题的方法:
在您的UISlider子类中,执行以下操作:
-(void)awakeFromNib { [super awakeFromNib]; UIImage* clearColorImage = [UIImage imageWithColor:[UIColor clearColor]]; [self setMinimumTrackImage:clearColorImage forState:UIControlStateNormal]; [self setMaximumTrackImage:clearColorImage forState:UIControlStateNormal]; }
用imageWithColor作为这个函数:
+ (UIImage*) imageWithColor:(UIColor*)color { return [UIImage imageWithColor:color andSize:CGSizeMake(1.0f, 1.0f)]; }
这将妥善照顾这个恼人的trackRectangle。
我花了太多的时间寻找解决这个问题的方法,希望能够节省一些时间给另一个可怜的灵魂;)。