【发布时间】:2011-05-18 15:56:07
【问题描述】:
我想为滑块的拇指添加一个标签,该标签应该显示滑块的值,并且当拇指被拖向右侧时也会发生变化。 可以吗??
任何 cmets 或建议将不胜感激。
【问题讨论】:
标签: ios objective-c iphone uislider
我想为滑块的拇指添加一个标签,该标签应该显示滑块的值,并且当拇指被拖向右侧时也会发生变化。 可以吗??
任何 cmets 或建议将不胜感激。
【问题讨论】:
标签: ios objective-c iphone uislider
我从滑块 (UIImageView) 中抓取拇指图像并将我的标签添加到其中。干净整洁。
UIImageView *handleView = [slider.subviews lastObject];
UILabel *label = [[UILabel alloc] initWithFrame:handleView.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
[handleView addSubview:label];
self.sliderLabel = label;
然后,您可以随时更改 label.text。
注意:UISlider 的子视图顺序可能会在未来发生变化,但拇指不太可能不再是最顶层视图,因为它始终是滑块中的主要交互点。
Swift 3 -- 更详细的示例(在 IB 中链接您的滑块)
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var slider: UISlider!
var sliderLabel: UILabel?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let handleView = slider.subviews.last as? UIImageView {
let label = UILabel(frame: handleView.bounds)
label.backgroundColor = .clear
label.textAlignment = .center
handleView.addSubview(label)
self.sliderLabel = label
//set label font, size, color, etc.
label.text = "!!"
}
}
}
【讨论】:
您可以执行与此示例类似的操作,将文本直接绘制到您的拇指图像上。这是一个粗略的示例,因此您需要对其进行更改以使其对您的项目有意义。
- (IBAction)sliderValueChanged:(id)sender {
UISlider *aSlider = (UISlider *)sender;
NSString *strForThumbImage =
[NSString stringWithFormat:@"%.0f", aSlider.value * 100]
UIImage *thumbImage = [self addText:self.thumbImage
text:strForThumbImage];
[aSlider setThumbImage:thumbImage forState:aSlider.state];
}
//Add text to UIImage
-(UIImage *)addText:(UIImage *)img text:(NSString *)text1{
int w = img.size.width;
int h = img.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate( NULL,
w,
h,
8,
4 * w,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
char* text= (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];
CGContextSelectFont(context, "Arial",12, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
CGContextShowTextAtPoint(context,3,8,text, strlen(text));
CGImageRef imgCombined = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIImage *retImage = [UIImage imageWithCGImage:imgCombined];
CGImageRelease(imgCombined);
return retImage;
}
【讨论】:
Swift 3.2 中自定义类的简单实现。这对我来说效果很好。
class ThumbTextSlider: UISlider {
var thumbTextLabel: UILabel = UILabel()
private var thumbFrame: CGRect {
return thumbRect(forBounds: bounds, trackRect: trackRect(forBounds: bounds), value: value)
}
override func layoutSubviews() {
super.layoutSubviews()
thumbTextLabel.frame = thumbFrame
thumbTextLabel.text = Double(value).roundTo(places: 1).description
}
override func awakeFromNib() {
super.awakeFromNib()
addSubview(thumbTextLabel)
thumbTextLabel.textAlignment = .center
thumbTextLabel.layer.zPosition = layer.zPosition + 1
}
}
希望对你有帮助:)
【讨论】:
在 Interface Builder 中添加 UISlider 和 UILabel。创建 IBOutlets 以在代码中访问它们并添加 IBAction 以响应滑块值的变化。
然后在你的代码中写:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.slider addSubview:self.label];
[self valueChanged:self.slider];
}
- (IBAction)valueChanged:(id)sender {
self.label.center = CGPointMake(self.slider.value*self.slider.bounds.size.width, 40);
self.label.text = [NSString stringWithFormat:@"%0.2f", self.slider.value];
}
编辑: 要使用代码创建滑块和标签,请添加:
-(void)loadView {
[super loadView];
self.slider = [[[UISlider alloc] initWithFrame:CGRectMake(50, 150, 200, 30)] autorelease];
self.label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 30)] autorelease];
[self.label setBackgroundColor:[UIColor clearColor]];
[self.slider addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:self.slider];
}
【讨论】:
您可以使用-thumbRectForBounds:trackRect:value:] 访问滑块的缩略图视图的矩形,因此如果您添加一个UILabel 子视图,您可以使用此返回的矩形将其与-layoutSubviews 中的缩略图视图对齐。
但是,如果您想使用 Autolayout 将标签与拇指图像对齐,则需要直接访问拇指的 UIImageView。我一般不热衷于探索 UIKit 套件组件的子视图,但我认为您可以使用公共 API 的详细信息以面向未来的方式搜索图像视图:
- (UIImageView*) thumbImageView {
__block UIImageView *imageView = nil;
[self.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(UIImageView *candidate, NSUInteger idx, BOOL *stop)
{
if ([candidate isKindOfClass:[UIImageView class]] && candidate.image ==
[self thumbImageForState:UIControlStateNormal])
{
imageView = candidate;
*stop = YES;
}
}];
return imageView;
}
API 提供了为拇指设置UIImage 的功能,因此您可以将其用作测试以确保您没有获得其他图像视图。如果您自己明确设置缩略图图像,这会更加安全(因为将来可能更改滑块以绘制缩略图图像并不是不可能...)。此外,拇指图像视图当前是最后一个子视图(不能保证继续前进),所以我在这里进行反向枚举,希望尽可能快地得到它,同时不对它的索引做出假设。
注意:我不得不懒惰地创建我的拇指标签,因为UISlider 的子视图似乎如此。
【讨论】:
让这变得又好又简单..首先这是最终结果
现在,代码:
UILabel *sl = [UILabel new];
[v addSubview:sl];
[sl constraintHeightEqualTo:12 widthTo:26];
UIImageView *handleView = [slider.subviews lastObject];
[self.view constraintVerticalSpacingSubviewsFromBottomView:s toTopView:sl constant:10];
[self.view constraintCenterXOfView:sl equalToView:handleView];
[sl setText:@"100%"];
[sl setFont:[UIFont systemFontOfSize:10]];
self.sliderLabel = sl;
以上方法来自我使用的NSLayoutConstraint 类别(即将推出)
- (id)constraintHeightEqualTo:(CGFloat)height widthTo:(CGFloat)width
{
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
[self constraintHeightEqualTo:height];
[self constraintWidthEqualTo:width];
return self;
}
- (id)constraintVerticalSpacingSubviewsFromBottomView:(UIView *)fromView toTopView:(UIView *)toView constant:(CGFloat)constant
{
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:fromView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:toView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:constant];
[self addConstraint:cn];
return self;
}
- (id)constraintCenterXOfView:(UIView *)fromView equalToView:(UIView *)toView constant:(CGFloat)constant
{
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:fromView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:toView
attribute:NSLayoutAttributeCenterX
multiplier:1 constant:constant];
[self addConstraint:cn];
return self;
}
【讨论】:
- (IBAction)valueChangedSlider:(id)sender {
handleView = [_slider.subviews lastObject];
label = [[UILabel alloc] initWithFrame:handleView.bounds];
label = (UILabel*)[handleView viewWithTag:1000];
if (label==nil) {
label = [[UILabel alloc] initWithFrame:handleView.bounds];
label.tag = 1000;
[label setFont:[UIFont systemFontOfSize:12]];
label.textColor = [UIColor redColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
[handleView addSubview:label];
}
label.text = [NSString stringWithFormat:@"%0.2f", self.slider.value];
}
【讨论】:
好吧,我继承了 UISlider 并覆盖了 NSControl 的方法。您只需要将您的课程更改为故事板
可以根据需要在拇指上方添加I标签。
class CustomSlider: UISlider {
let label = UILabel()
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
let track = super.beginTracking(touch, with: event)
label.text = "\(Int(self.value))"
label.frame = CGRect.init(x: self.thumbCenterX, y: -10, width: 20, height: 20)
self.addSubview(label)
return track
}
override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
let track = super.continueTracking(touch, with: event)
label.frame = CGRect.init(x: self.thumbCenterX - 5 , y: 6, width: 30, height: 20)
label.text = "\(Int(self.value))"
return track
}
override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
super.endTracking(touch, with: event)
label.removeFromSuperview()
}}
extension UISlider {
var thumbCenterX: CGFloat {
let trackRect = self.trackRect(forBounds: frame)
let thumbRect = self.thumbRect(forBounds: bounds, trackRect: bounds, value: value)
return thumbRect.midX
}}
【讨论】: