【问题标题】:Objactive C UISlider changing minimum track image onlyObjective C UISlider 仅更改最小轨迹图像
【发布时间】:2019-10-31 13:02:31
【问题描述】:

我正在尝试使用带有 CAGradientLayer 的图像来设置滑块的MinimumTrackImage,比如说使用蓝色和红色。

发生的情况是,整个轨道获得渐变颜色,它以红色开始,向右滑动拇指显示蓝色。 我希望颜色从红色开始到蓝色直到拇指,并随着拇指的移动而“伸展”。

有什么想法吗?我虽然关于设置slider.maximumValue = slider...width 并在我听滑块值更改时更改渐变图像,但它不起作用

【问题讨论】:

    标签: objective-c gradient uislider


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多