UISlider捕捉到固定数量的步骤(如iOS 7设置应用中的文字大小)

Mat*_*Vad 50 iphone xcode objective-c uislider ios

我正在尝试创建一个UISlider允许您从数组中选择的东西.每个滑块位置应该是等距的,滑块应该对齐每个位置,而不是在它们之间平滑滑动.(这是在滑动件的行为Settings> General> Text Size,这是在IOS 7.引入)

iOS 7文字大小滑块

我想要选择的数字是: -3, 0, 2, 4, 7, 10, and 12.

(我对Objective-C很新,所以一个完整的代码示例比代码片段更有用.=)

mat*_*tsr 119

其他一些答案可以解决,但这会在滑块的每个位置之间提供相同的固定空间.在此示例中,您将滑块位置视为包含您感兴趣的实际数值的数组的索引.

@interface MyViewController : UIViewController {
    UISlider *slider;
    NSArray *numbers;
}
@end

@implementation MyViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    slider = [[UISlider alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:slider];

    // These number values represent each slider position
    numbers = @[@(-3), @(0), @(2), @(4), @(7), @(10), @(12)];
    // slider values go from 0 to the number of values in your numbers array
    NSInteger numberOfSteps = ((float)[numbers count] - 1);
    slider.maximumValue = numberOfSteps;
    slider.minimumValue = 0;

    // As the slider moves it will continously call the -valueChanged: 
    slider.continuous = YES; // NO makes it call only once you let go
    [slider addTarget:self
               action:@selector(valueChanged:)
     forControlEvents:UIControlEventValueChanged];
}
- (void)valueChanged:(UISlider *)sender {
    // round the slider position to the nearest index of the numbers array
    NSUInteger index = (NSUInteger)(slider.value + 0.5);
    [slider setValue:index animated:NO];
    NSNumber *number = numbers[index]; // <-- This numeric value you want
    NSLog(@"sliderIndex: %i", (int)index);
    NSLog(@"number: %@", number);
}
Run Code Online (Sandbox Code Playgroud)

我希望有所帮助,祝你好运.

编辑:这是Swift 4中的一个版本,它将UISlider与回调子类化.

class MySliderStepper: UISlider {
    private let values: [Float]
    private var lastIndex: Int? = nil
    let callback: (Float) -> Void

    init(frame: CGRect, values: [Float], callback: @escaping (_ newValue: Float) -> Void) {
        self.values = values
        self.callback = callback
        super.init(frame: frame)
        self.addTarget(self, action: #selector(handleValueChange(sender:)), for: .valueChanged)

        let steps = values.count - 1
        self.minimumValue = 0
        self.maximumValue = Float(steps)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    @objc func handleValueChange(sender: UISlider) {
        let newIndex = Int(sender.value + 0.5) // round up to next index
        self.setValue(Float(newIndex), animated: false) // snap to increments
        let didChange = lastIndex == nil || newIndex != lastIndex!
        if didChange {
            let actualValue = self.values[newIndex]
            self.callback(actualValue)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你.这正是我想要的,并以教导我如何做的方式编写.再次感谢你! (3认同)

Bar*_*zyk 5

如果步骤之间有规则的空格,则可以将其用作15值:

@IBAction func timeSliderChanged(sender: UISlider) {

    let newValue = Int(sender.value/15) * 15
    sender.setValue(Float(newValue), animated: false)
}
Run Code Online (Sandbox Code Playgroud)

  • 这很容易实现,并且是简单案例的绝佳选择。我认为接受的答案(虽然仍然是一个不错的选择,当然更可定制)在大多数情况下是矫枉过正的,这应该足以满足大多数人想要做的事情。 (2认同)

tay*_*y08 5

这适用于我的特殊情况,使用@IBDesignable:

需要偶数,整数间隔:

@IBDesignable
class SnappableSlider: UISlider {

    @IBInspectable
    var interval: Int = 1

    override init(frame: CGRect) {
        super.init(frame: frame)
        setUpSlider()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setUpSlider()
    }

    private func setUpSlider() {
        addTarget(self, action: #selector(handleValueChange(sender:)), for: .valueChanged)
    }

    @objc func handleValueChange(sender: UISlider) {
        let newValue =  (sender.value / Float(interval)).rounded() * Float(interval)
        setValue(Float(newValue), animated: false)
    }
}
Run Code Online (Sandbox Code Playgroud)