捕捉到固定步数的UISlider(如iOS 7设置应用程序中的文本大小)
我正在尝试创建一个捕捉到固定步数的UISlider(如iOS 7设置应用程序中的文本大小),ios,objective-c,iphone,xcode,uislider,Ios,Objective C,Iphone,Xcode,Uislider,我正在尝试创建一个UISlider,它允许您从数字数组中进行选择。每个滑块位置应等距,滑块应捕捉到每个位置,而不是在它们之间平滑滑动。(这是iOS 7中引入的设置常规文本大小中滑块的行为。) 我想从中选择的数字是:-3、0、2、4、7、10和12。 (我对Objective-C非常陌生,所以一个完整的代码示例比一个代码片段要有用得多。=)答案基本上是一样的 要修改它以适应您的情况,您需要创建一个舍入函数,该函数只返回您想要的值。例如,你可以做一些简单的事情(尽管很粗糙),比如: -(int)r
UISlider
,它允许您从数字数组中进行选择。每个滑块位置应等距,滑块应捕捉到每个位置,而不是在它们之间平滑滑动。(这是iOS 7中引入的设置
常规
文本大小
中滑块的行为。)
我想从中选择的数字是:-3、0、2、4、7、10和12。
(我对Objective-C非常陌生,所以一个完整的代码示例比一个代码片段要有用得多。=)答案基本上是一样的 要修改它以适应您的情况,您需要创建一个舍入函数,该函数只返回您想要的值。例如,你可以做一些简单的事情(尽管很粗糙),比如:
-(int)roundSliderValue:(float)x {
if (x < -1.5) {
return -3;
} else if (x < 1.0) {
return 0;
} else if (x < 3.0) {
return 2;
} else if (x < 5.5) {
return 4;
} else if (x < 8.5) {
return 7;
} else if (x < 11.0) {
return 10;
} else {
return 12;
}
}
最后,实施更改:
-(void)valueChanged:(id)slider {
[slider setValue:[self roundSliderValue:slider.value] animated:NO];
}
其他一些答案是有效的,但这将在滑块的每个位置之间提供相同的固定空间。在本例中,您将滑块位置视为包含您感兴趣的实际数值的数组的索引
@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);
}
与PengOne的方法类似,但我进行了手动取整,以使其更清楚发生了什么
- (IBAction)sliderDidEndEditing:(UISlider *)slider {
// default value slider will start at
float newValue = 0.0;
if (slider.value < -1.5) {
newValue = -3;
} else if (slider.value < 1) {
newValue = 0;
} else if (slider.value < 3) {
newValue = 2;
} else if (slider.value < 5.5) {
newValue = 4;
} else if (slider.value < 8.5) {
newValue = 7;
} else if (slider.value < 11) {
newValue = 10;
} else {
newValue = 12;
}
slider.value = newValue;
}
- (IBAction)sliderValueChanged:(id)sender {
UISlider *slider = sender;
float newValue = 0.0;
if (slider.value < -1.5) {
newValue = -3;
} else if (slider.value < 1) {
newValue = 0;
} else if (slider.value < 3) {
newValue = 2;
} else if (slider.value < 5.5) {
newValue = 4;
} else if (slider.value < 8.5) {
newValue = 7;
} else if (slider.value < 11) {
newValue = 10;
} else {
newValue = 12;
}
// and if you have a label displaying the slider value, set it
[yourLabel].text = [NSString stringWithFormat:@"%d", (int)newValue];
}
-(iAction)滑块定义编辑:(UISlider*)滑块{
//默认值滑块将从
float newValue=0.0;
如果(滑块值<-1.5){
newValue=-3;
}else if(slider.value<1){
newValue=0;
}else if(slider.value<3){
newValue=2;
}否则如果(滑块值<5.5){
newValue=4;
}否则如果(滑块值<8.5){
newValue=7;
}else if(slider.value<11){
newValue=10;
}否则{
newValue=12;
}
slider.value=newValue;
}
-(iAction)sliderValueChanged:(id)发件人{
UISlider*滑块=发送器;
float newValue=0.0;
如果(滑块值<-1.5){
newValue=-3;
}else if(slider.value<1){
newValue=0;
}else if(slider.value<3){
newValue=2;
}否则如果(滑块值<5.5){
newValue=4;
}否则如果(滑块值<8.5){
newValue=7;
}else if(slider.value<11){
newValue=10;
}否则{
newValue=12;
}
//如果有显示滑块值的标签,请将其设置为
[yourLabel].text=[NSString stringWithFormat:@“%d”,(int)newValue];
}
如果步骤之间有规则的空格,则可以将其用于15
值:
@IBAction func timeSliderChanged(sender: UISlider) {
let newValue = Int(sender.value/15) * 15
sender.setValue(Float(newValue), animated: false)
}
这适用于我的特殊情况,使用@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)
}
}
如果任何人也需要捕捉动画,则可以执行以下操作:
slider.isContinuous=false执行相同操作
在视图控制器中添加以下@iAction
:
@iAction func滑块移动(\uSlider:UISlider){
让stepCount=10
让roundedCurrent=(slider.value/Float(stepCount)).rounded()
设newValue=Int(舍入当前)*步数
slider.setValue(Float(newValue),动画:true)
}
我的灵感来自于可能的复制品不,它不是。因为我没有一个固定的步骤5或10。我需要能够从滑块上的7个固定值中进行选择。另外,如果我真的可以使用你链接到的那个,我不知道如何实现代码并为我的配件进行更改。这可能是正确的方法,但我需要详细说明。对链接问题的高度投票的答案可以根据您的需要进行调整。你为什么不试试,然后再问一下你有没有问题?好的,这是个好消息。但是你能不能给我详细解释一下,也许是在回答这个问题时,提供一个示例代码,告诉我如何使代码适应我的需要?我应该在哪里添加代理?我该如何更改该值,使其适合我的7个不同刻度?正如我在问题中提到的,我对Objective-C相当陌生——我不能只看一段代码就想“啊,我可以改变这个,然后……”,但是:)非常感谢。这正是我想要的,并且以一种教我如何去做的方式来写。再次感谢你!所以我把“数字”改成了一个包含100多个数据点的数组。。。。如何更改UISlider的代码,使其相对于数据点的数量滑动?我知道“索引”需要更改,但是……/。。。。我想我会在几个小时内找到答案,但我认为其他一些人希望看到一个动态数组的答案,其中滑块可以有1到数千个索引……)如果将其设置为continuous values=NOslider.continuous=NO,则只需简单地更改代码即可接受静态或动态数组值,您将获得一个附加的upvote代码>它允许用户在拖动滑块时进行更平滑的操作。由于它仅在用户完成拖动滑块并将其移动到最接近的整数值时计算valueChanged
函数。@MatiasVad我需要与所讨论的相同的UI,我指的是小步垂直线,我搜索了它,但没有找到解决方案。这很容易实现,对于简单的情况来说是一个很好的选择。我认为被接受的答案(虽然仍然是一个很好的选择,当然更可定制)对于大多数情况来说是过分的,这应该足以满足大多数人的需求。太棒了
@IBAction func timeSliderChanged(sender: UISlider) {
let newValue = Int(sender.value/15) * 15
sender.setValue(Float(newValue), animated: false)
}
@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)
}
}