ios 如何实现一个最小轨迹从中心(值=0)开始而不是从左边开始的滑块

83qze16e  于 2023-01-22  发布在  iOS
关注(0)|答案(3)|浏览(133)

就像这样

有没有什么方法可以只用子类UISlider来实现这一点?

编辑:也许我误导了您,但这确实是一个UI问题。

vnzz0bqm

vnzz0bqm1#

解决它。
1.创建 fakeThumbImageViewfakeMinTrackImageViewfakeMaxTrackImageView 并将帧设置为thumbRectForBounds:trackRect:value:
1.覆盖setMinimumTrackTintColor:setMinimumTrackImage:和其他一些方法(总共6个)
1.在初始化方法中调用super setMinimumTrackTintColor:[UIColor clearColor]
1.建议制作fakeXXXXImageView.layer.zPosition=1000

gwo2fgha

gwo2fgha2#

首先设置minimumTrackTintColor = .clearself.maximumTrackTintColor = .clear,然后创建一个视图,该视图与音轨的width/height相同,并放在UISlider的正下方,通过该视图,可以将leadingConstrainttrailingConstraint设置为在中间压缩(初始位置,当UISlider值为0.5时)。因此,无论何时UISlider值发生变化,您都可以重新计算约束以实现所需的结果。

icnyk63a

icnyk63a3#

如果您对使用私有API感兴趣,

//  UIView+Swizzle_UISlideriOSVisualElement.m

#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import <objc/message.h>

@implementation UIView (Swizzle_UISlideriOSVisualElement)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleWithClass:NSClassFromString(@"_UISlideriOSVisualElement")
              originalSelector:NSSelectorFromString(@"didPerformLayout")
              swizzledSelector:@selector(_UISlideriOSVisualElement_swizzledDidPerformLayout)];
    });
}

+ (void)swizzleWithClass:(Class)targetClass originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
    Method originalMethod = class_getInstanceMethod(targetClass, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(targetClass, swizzledSelector);
    
    IMP originalImp = method_getImplementation(originalMethod);
    IMP swizzledImp = method_getImplementation(swizzledMethod);
    
    class_replaceMethod(targetClass, swizzledSelector, originalImp, nil);
    class_replaceMethod(targetClass, originalSelector, swizzledImp, nil);
}

- (void)_UISlideriOSVisualElement_swizzledDidPerformLayout {
    [self _UISlideriOSVisualElement_swizzledDidPerformLayout];
    
    UISlider *slider = ((UISlider * (*)(UIView *, SEL))objc_msgSend)(self, NSSelectorFromString(@"slider"));
    float totalValue = (fabsf(slider.minimumValue) + fabsf(slider.maximumValue));
    if (totalValue == 0.0f) return;
    
    UIView *_minTrackClipView = [self valueForKey:@"_minTrackClipView"];
    UIView *_maxTrackClipView = [self valueForKey:@"_maxTrackClipView"];
    
//    UIImageView *minTrackView = ((UIImageView * (*)(UIView *, SEL))objc_msgSend)(self, NSSelectorFromString(@"minTrackView"));
    UIImageView *maxTrackView = ((UIImageView * (*)(UIView *, SEL))objc_msgSend)(self, NSSelectorFromString(@"maxTrackView"));
    
    float totalWidth = _minTrackClipView.frame.size.width + _maxTrackClipView.frame.size.width;
    
    _maxTrackClipView.frame = CGRectMake(_minTrackClipView.frame.origin.x,
                                         _maxTrackClipView.frame.origin.y,
                                         _minTrackClipView.frame.size.width + _maxTrackClipView.frame.size.width,
                                         _maxTrackClipView.frame.size.height);
    maxTrackView.frame = CGRectMake(0.0f,
                                    maxTrackView.frame.origin.y,
                                    maxTrackView.frame.size.width,
                                    maxTrackView.frame.size.height);
    
    float percentage = (slider.value / totalValue);
    
    _minTrackClipView.frame = CGRectMake(_minTrackClipView.frame.origin.x + (totalWidth / 2.0f) + ((percentage > 0.0f) ? 0.0f : totalWidth * percentage),
                                         _minTrackClipView.frame.origin.y,
                                         fabsf(totalWidth * percentage),
                                         _minTrackClipView.frame.size.height);
}

@end

GitHub

相关问题