ios - 捕捉固定步数的 UISlider(如 iOS 7 设置应用程序中的文本大小)

标签 ios objective-c iphone xcode uislider

我正在尝试创建一个 UISlider,让您可以从一组数字中进行选择。每个 slider 位置应该是等距的,并且 slider 应该捕捉到每个位置,而不是在它们之间平滑滑动。 (这是 Settings > General > Text Size 中 slider 的行为,在 iOS 7 中引入。)

iOS 7 Text Size Slider

我要选择的数字是:-3、0、2、4、7、10 和 12。

(我是 Objective-C 的新手,所以完整的代码示例比代码片段更有帮助。=)

最佳答案

其他一些答案有效,但这会在 slider 的每个位置之间为您提供相同的固定空间。在此示例中,您将 slider 位置视为数组的索引,该数组包含您感兴趣的实际数值。

@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);
}

希望对你有帮助,祝你好运。

编辑:这是 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 {
            lastIndex = newIndex
            let actualValue = self.values[newIndex]
            self.callback(actualValue)
        }
    }
}

关于ios - 捕捉固定步数的 UISlider(如 iOS 7 设置应用程序中的文本大小),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8219056/

相关文章:

ios - iOS中UITableView的自定义设计

ios - 事件指示器不会停止或隐藏

html - 减少 phonegap 应用程序 ios 中的 html 文件加载时间?

ios - 如何为 iPhone 5 更新完全由图像组成的应用程序

objective-c - OSX cocoa 应用程序 : Which method for rescaling an image is best with respect to image quality?

ios - Gamecenter init/authentication 使 SpriteKit 的 Sprite 移动滞后

IOS Reveal View - 在另一个 UIViewController 中触发函数

iphone - 初学者在 iPhone 上常犯的多线程错误

ios - TestFlight 不会向外部用户发送邀请

iphone - 从数据库检索数据到不同的 View Controller