Objactive C UISlider меняет только минимальное изображение дорожки - PullRequest
0 голосов
/ 31 октября 2019

Я пытаюсь установить MinimTrackImage ползунка, используя изображение с CAGradientLayer, скажем, используя синий и красный цвета.

что происходит, когда полная дорожка получает цвет градиента, она начинается с красного, и скользитБольшой палец справа показывает синий цвет. Я хочу, чтобы цвет начинался с красного до синего до большого пальца, и «растягивался» при движении большого пальца.

есть идеи? Я думал о том, чтобы установить slider.maximumValue = slider ... width и изменить изображение градиента, когда я слушаю изменение значения слайдера, но оно не работает

1 Ответ

1 голос
/ 31 октября 2019

Не думаю, что вам удастся попытаться установить минимальное изображение дорожки.

Параметры - это полностью настраиваемый ползунок ...

или

Установитьминимальное изображение дорожки для четкого изображения, добавьте imageView с градиентным изображением за ползунком, растяните рамку imageView, чтобы соответствовать движению большого пальца.

Вот пример:

enter image description here

и код (просто отправная точка ... было бы гораздо лучше обернуть его в подкласс):


SliderTestViewController. ч

//
//  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
...