Objective C UISlider 仅更改最小轨迹图像
Posted
技术标签:
【中文标题】Objective C UISlider 仅更改最小轨迹图像【英文标题】:Objactive C UISlider changing minimum track image only 【发布时间】:2019-10-31 13:02:31 【问题描述】:我正在尝试使用带有 CAGradientLayer 的图像来设置滑块的MinimumTrackImage,比如说使用蓝色和红色。
发生的情况是,整个轨道获得渐变颜色,它以红色开始,向右滑动拇指显示蓝色。 我希望颜色从红色开始到蓝色直到拇指,并随着拇指的移动而“伸展”。
有什么想法吗?我虽然关于设置slider.maximumValue = slider...width 并在我听滑块值更改时更改渐变图像,但它不起作用
【问题讨论】:
【参考方案1】:我认为您尝试设置最小轨道图像不会成功。
选项是一个完全自定义的滑块...
或
将最小轨道图像设置为清晰图像,在滑块后面添加带有渐变图像的imageView,拉伸imageView的框架以匹配拇指移动。
这是一个例子:
和代码(只是一个起点......将其包装到子类中会更好):
SliderTestViewController.h
//
// SliderTestViewController.h
//
// Created by Don Mag on 10/31/19.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SliderTestViewController : UIViewController
@end
NS_ASSUME_NONNULL_END
SliderTestViewController.m
//
// SliderTestViewController.m
//
// Created by Don Mag on 10/31/19.
//
#import "SliderTestViewController.h"
#import "UIImage+Utils.h"
@interface SliderTestViewController ()
@property (strong, nonatomic) UIImageView *theFakeSliderTrackImageView;
@property (strong, nonatomic) UISlider *theSlider;
@property (strong, nonatomic) NSLayoutConstraint *imgWidthConstraint;
@end
@implementation SliderTestViewController
- (void)viewDidLoad
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// instantiate a slider
_theSlider = [UISlider new];
// instantiate an image view to use as our custom / fake "left side" of the slider track
_theFakeSliderTrackImageView = [UIImageView new];
// we want the image to stretch
_theFakeSliderTrackImageView.contentMode = UIViewContentModeScaleToFill;
// create a horizontal gradient image to use for our "left side" of the slider track
// the image will be stretched... using a width of 128 seems reasonable
UIImage *gradImg = [UIImage gradientImageWithSize:CGSizeMake(128.0, 4.0) startColor:[UIColor blueColor] endColor:[UIColor redColor] startPoint:CGPointMake(0.0, 0.0) endPoint:CGPointMake(1.0, 0.0)];
// set the gradient image to our image view
_theFakeSliderTrackImageView.image = gradImg;
// create a clear image to use for the slider's min track image
UIImage *clearImg = [UIImage imageWithColor:[UIColor clearColor] size:CGSizeMake(1.0, 1.0)];
// set min track image to clear image
[_theSlider setMinimumTrackImage:clearImg forState:UIControlStateNormal];
// set max track image if desired
// [_theSlider setMaximumTrackImage:anImage forState:UIControlStateNormal];
_theFakeSliderTrackImageView.translatesAutoresizingMaskIntoConstraints = NO;
_theSlider.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_theFakeSliderTrackImageView];
[self.view addSubview:_theSlider];
[NSLayoutConstraint activateConstraints:@[
// constrain the slider centerY with 20-pts leading / trailing
[_theSlider.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
[_theSlider.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20.0],
[_theSlider.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20.0],
// constrain image view centerY to slider centerY
[_theFakeSliderTrackImageView.centerYAnchor constraintEqualToAnchor:_theSlider.centerYAnchor constant:0.0],
// constrain image view leading to slider leading
[_theFakeSliderTrackImageView.leadingAnchor constraintEqualToAnchor:_theSlider.leadingAnchor constant:0.0],
// image view height to 5-pts (adjust as desired)
[_theFakeSliderTrackImageView.heightAnchor constraintEqualToConstant:5.0],
]];
// init imageView width constraint to 0.0
_imgWidthConstraint = [_theFakeSliderTrackImageView.widthAnchor constraintEqualToConstant:0.0];
_imgWidthConstraint.active = YES;
[_theSlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
- (void)viewDidLayoutSubviews
[super viewDidLayoutSubviews];
[self updateSliderGradientImage];
- (void)updateSliderGradientImage
// set "fake track" imageView width to origin.x of thumb rect (plus 2 for good measure)
CGRect trackRect = [_theSlider trackRectForBounds:_theSlider.bounds];
CGRect thumbRect = [_theSlider thumbRectForBounds:_theSlider.bounds trackRect:trackRect value:_theSlider.value];
_imgWidthConstraint.constant = thumbRect.origin.x + 2;
- (void)sliderChanged:(id)sender
[self updateSliderGradientImage];
@end
UIImage+Utils.h
//
// UIImage+Utils.h
//
// Created by Don Mag on 10/31/19.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIImage (Utils)
+ (nullable UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size;
+ (nullable UIImage *)gradientImageWithSize:(CGSize)size startColor:(UIColor *)startColor endColor:(UIColor *)endColor startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint;
@end
NS_ASSUME_NONNULL_END
UIImage+Utils.m
//
// UIImage+Utils.m
//
// Created by Don Mag on 10/31/19.
//
#import "UIImage+Utils.h"
@implementation UIImage (Utils)
+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
if (!color || size.height < 1 || size.width < 1)
return nil;
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size];
UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context)
[color setFill];
[context fillRect:renderer.format.bounds];
];
return image;
+ (UIImage *)gradientImageWithSize:(CGSize)size startColor:(UIColor *)startColor endColor:(UIColor *)endColor startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint
if (!startColor || !endColor)
return nil;
CFArrayRef colors = (__bridge CFArrayRef) [NSArray arrayWithObjects:
(id)startColor.CGColor,
(id)endColor.CGColor,
nil];
CGGradientRef g = CGGradientCreateWithColors(nil, colors, nil);
startPoint.x *= size.width;
startPoint.y *= size.height;
endPoint.x *= size.width;
endPoint.y *= size.height;
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size];
UIImage *gradientImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext)
CGContextDrawLinearGradient(rendererContext.CGContext, g, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
];
return gradientImage;
@end
【讨论】:
以上是关于Objective C UISlider 仅更改最小轨迹图像的主要内容,如果未能解决你的问题,请参考以下文章
在 Objective C 中为 UISlider 创建没有情节提要的 Outlet 和 Action
Objective C / iPhone - 如何将 UISlider 绑定到代码
如何在 Objective-C 中的 UISlider 上添加标记? [关闭]
Objective-c,AVPlayer 中的 UISlider 无法正常工作,在洗涤器之后