Slider auto motion

Hello

here I am again.

I need help again.

I'm changing a value into the textfield1 using the slider1.

And I have another textfield2 with slider2.

In textfield1 I introduce radius value of a circle. And in textfield2 I obtain the diameter of the circle.

But if I change value in textfield2, automatically the value in textfield1 changes.

Now I want the thumb of each slider to move alone if I change the values of each textfield and also if I move manually the thumb of one slider.

How can I do it?

I don't succeed in doing that.

Thanks

Accepted Reply

I suspect your conversion to Int may cause the difference.


could add print statements to see:


@IBAction func sliderValue1(_ sender: UISlider) {
  print("sender.value", sender.value)
  textValue.text = String(Int(sender.value))
  print("sliderValue1", sliderValue1)
  print("sliderValue2 before", sliderValue2)

  UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseInOut, animations: {
      self.sliderValue2.setValue(Float(sliderValue1), animated: true)}, completion: nil)   }

print("sliderValue2 after", sliderValue2)

Replies

There are several ways to do this.


You can do it directly in the actions for sliders or on update of textFields.


But it is better to use notifications.

You send notification when you change textfield1, slider1.

The action for notification will update all others : textfield1, slider1, textfield2, slider2.


You send notification when you change textfield2, slider2.

The action for notification will update all others : textfield1, slider1, textfield2, slider2.


Add observers for the 2 notifications in viewController.


If you post your present code for the view controller, it will be possible to be more specific.

import UIKit


class ViewDiamTabBarController: UIViewController {


@IBOutlet weak var Label1: UILabel!

@IBOutlet weak var diamTextValue: UITextField!

@IBOutlet weak var diamSliderValue: UISlider!

@IBOutlet weak var label2: UILabel!

@IBOutlet weak var altoTextValue: UITextField!

@IBOutlet weak var altoSliderValue: UISlider!

@IBOutlet weak var lockButton: UIButton!

@IBOutlet weak var label3: UILabel!

@IBOutlet weak var anchoTextValue: UITextField!

@IBOutlet weak var anchoSliderValue: UISlider!

@IBOutlet weak var label4: UILabel!

@IBOutlet weak var perimetroLabel: UILabel!

@IBOutlet weak var seccionLabel: UILabel!

@IBOutlet weak var perimRectLabel: UILabel!

@IBOutlet weak var calcularButton: UIButton!

var diametroValue1 = 0

var diametroValue2 = 0

var altoValue = 0

var anchoValue = 0

var seccionValue = 0

var perimCircValue1 = 0

var perimCircValue2 = 0

var seccCircValue1 = 0

var seccCircValue2 = 0

var perimRectValue1 = 0

var perimRectValue2 = 0

@IBAction func diamTextEntry(_ sender: UITextField) {

let diamAmount = Double(diamTextValue.text!)

let altoAmount = Double(altoTextValue.text!)

let alertMessage = "Falta introducir un parámetro !"

let alertMessage2 = "Los valores introducidos deben ser superiores a 0 !"

if (diamAmount != nil && altoAmount != nil){

if (diamAmount! > 0 && altoAmount! > 0){

let seccionValue = .pi*(diamAmount!/2)*(diamAmount!/2)

let anchoValue = Double(round(1000*(seccionValue/altoAmount!))/1000)

anchoTextValue.text = String(Int(anchoValue))

} else {

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage2, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

} else {

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

}

@IBAction func altoTextEntry(_ sender: UITextField) {

let diamAmount = Double(diamTextValue.text!)

let altoAmount = Double(altoTextValue.text!)

let alertMessage = "Falta introducir un parámetro !"

let alertMessage2 = "Los valores introducidos deben ser superiores a 0 !"

if (diamAmount != nil && altoAmount != nil) {

if (diamAmount! > 0 && altoAmount! > 0) {

let seccionValue = .pi*(diamAmount!/2)*(diamAmount!/2)

let anchoValue = Double(round(1000*(seccionValue/altoAmount!))/1000)


anchoTextValue.text = String(Int(anchoValue))

} else {

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage2, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

} else {

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

}

@IBAction func anchoTextEntry(_ sender: UITextField) {

let diamAmount = Double(diamTextValue.text!)

let anchoAmount = Double(anchoTextValue.text!)

let altoAmount = Double(altoTextValue.text!)

let alertMessage = "Falta introducir un parámetro !"

let alertMessage2 = "Los valores introducidos deben ser superiores a 0 !"

if (diamAmount != nil && anchoAmount != nil) && altoAmount != nil {

if (diamAmount! > 0 && altoAmount! > 0 && anchoAmount! > 0) {

let seccionValue = .pi*(diamAmount!/2)*(diamAmount!/2)

let altoValue = Double(round(1000*(seccionValue/anchoAmount!))/1000)


altoTextValue.text = String(Int(altoValue))

} else {

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage2, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

} else {

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

}

@IBAction func diamSliderMove(_ sender: UISlider) {

diamTextValue.text = String(Int(sender.value))

let diamAmount = Double(diamTextValue.text!)

let altoAmount = Double(altoTextValue.text!)

let seccionValue = .pi*(diamAmount!/2)*(diamAmount!/2)

let anchoValue = Double(round(1000*(seccionValue/altoAmount!))/1000)

anchoTextValue.text = String(Int(anchoValue))

}

@IBAction func altoSliderMove(_ sender: UISlider) {

altoTextValue.text = String(Int(sender.value))

let diamAmount = Double(diamTextValue.text!)

let altoAmount = Double(altoTextValue.text!)

let seccionValue = .pi*(diamAmount!/2)*(diamAmount!/2)

let anchoValue = Double(round(1000*(seccionValue/altoAmount!))/1000)

anchoTextValue.text = String(Int(anchoValue))

}

@IBAction func anchoSliderMove(_ sender: UISlider) {

anchoTextValue.text = String(Int(sender.value))


let altoAmount = Double(altoTextValue.text!)

let anchoAmount = Double(anchoTextValue.text!)

let diamAmount = Double(diamTextValue.text!)

if lockButton.currentBackgroundImage == imageLiteral(resourceName: "lockred25")

{


let seccionValue = (altoAmount!)*(anchoAmount!)

let diametroValue1 = 2*sqrt((seccionValue)/(.pi))

let diametroValue2 = Double(round(1000*(diametroValue1))/1000)


diamTextValue.text = String(Int(diametroValue2))

} else {

let seccionValue = .pi*(diamAmount!/2)*(diamAmount!/2)

let altoValue = Double(round(1000*(seccionValue/anchoAmount!))/1000)

altoTextValue.text = String(Int(altoValue))

}

}

@IBAction func lockButtonPressed(_ sender: UIButton) {

if lockButton.currentBackgroundImage == imageLiteral(resourceName: "lockblue25")

{

lockButton.setBackgroundImage( imageLiteral(resourceName: "lockred25"), for: .normal)

} else {

lockButton.setBackgroundImage( imageLiteral(resourceName: "lockblue25"), for: .normal)

}

}

@IBAction func calcButtonPressed(_ sender: UIButton) {


let diamAmount = Double(diamTextValue.text!)

let altoAmount = Double(altoTextValue.text!)

let anchoAmount = Double(anchoTextValue.text!)

let alertMessage = "Falta introducir un parámetro !"


if (diamAmount != nil && altoAmount != nil && anchoAmount != nil){

let perimCircValue1 = .pi*(diamAmount!)/1000

let perimCircValue2 = Double(round(1000*perimCircValue1)/1000)

let PerimCircString = String(perimCircValue2)

perimetroLabel.text = PerimCircString

let seccCircValue1 = .pi*(diamAmount!/2000)*(diamAmount!/2000)

let seccCircValue2 = Double(round(1000*seccCircValue1)/1000)

let SeccCircString = String(seccCircValue2)

seccionLabel.text = SeccCircString


let perimRectValue1 = 2*((altoAmount!/1000)+(anchoAmount!/1000))

let perimRectValue2 = Double(round(1000*perimRectValue1)/1000)

let PerimRectString = String(perimRectValue2)

perimRectLabel.text = PerimRectString

} else{

let alert = UIAlertController(title: "Error de procedimiento", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.destructive){ (result : UIAlertAction) -> Void in print ("Cancel button selected")

}

let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ (result : UIAlertAction) -> Void in print ("Ok button selected")

}

alert.addAction(cancelAction)

alert.addAction(okAction)

self.present(alert, animated: true, completion: nil)

}

}

override func viewDidLoad() {

super.viewDidLoad()


Label1.layer.borderWidth = 1.0

Label1.layer.cornerRadius = 8

Label1.layer.borderColor = UIColor.lightGray.cgColor


diamTextValue.layer.borderWidth = 0.5

diamTextValue.layer.borderColor = UIColor.gray.cgColor


diamSliderValue.thumbTintColor = UIColor.lightGray


label2.layer.borderWidth = 1.0

label2.layer.cornerRadius = 8

label2.layer.borderColor = UIColor.lightGray.cgColor

altoTextValue.layer.borderWidth = 0.5

altoTextValue.layer.borderColor = UIColor.gray.cgColor

altoSliderValue.thumbTintColor = UIColor.lightGray

label3.layer.borderWidth = 1.0

label3.layer.cornerRadius = 8

label3.layer.borderColor = UIColor.lightGray.cgColor

anchoTextValue.layer.borderWidth = 0.5

anchoTextValue.layer.borderColor = UIColor.gray.cgColor

anchoSliderValue.thumbTintColor = UIColor.lightGray

label4.layer.borderWidth = 1.0

label4.layer.cornerRadius = 8

label4.layer.borderColor = UIColor.lightGray.cgColor

perimetroLabel.layer.borderWidth = 1.0

perimetroLabel.layer.borderColor = UIColor.lightGray.cgColor

seccionLabel.layer.borderWidth = 1.0

seccionLabel.layer.borderColor = UIColor.lightGray.cgColor

perimRectLabel.layer.borderWidth = 1.0

perimRectLabel.layer.borderColor = UIColor.lightGray.cgColor

calcularButton.layer.borderWidth = 1.0

calcularButton.layer.cornerRadius = 8

calcularButton.layer.borderColor = UIColor.gray.cgColor


let toolBar = UIToolbar()

toolBar.sizeToFit()

let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.doneClicked))

toolBar.setItems([doneButton], animated: false)

diamTextValue.inputAccessoryView = toolBar

altoTextValue.inputAccessoryView = toolBar

anchoTextValue.inputAccessoryView = toolBar

}


@objc func doneClicked() {

view.endEditing(true)

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

}

}

HI

I've tryed in another project, this code and found a way to do it.

But I can see how the thumb of the slider is not correctly aligned with the other slider. Is it normal?

How can I do to have slider2 following exactly the slider1 or slider3?


//

// ViewController.swift

// AnimatedSlider

//


import UIKit


class ViewController: UIViewController {

@IBOutlet weak var textValue: UITextField!

@IBOutlet weak var sliderValue1: UISlider!

@IBOutlet weak var sliderValue2: UISlider!

@IBOutlet weak var labelResult: UILabel!

@IBOutlet weak var sliderValue3: UISlider!

@IBOutlet weak var label3: UILabel!

@IBAction func sliderValue1Entry(_ sender: UISlider) {

textValue.text = String(Int(sender.value))

let textAmount = Int(textValue.text!)

var sliderOneValue = Int(sender.value)

var sliderTwoValue = Int(sliderValue1.value)

var sliderThreeValue = Int(sliderValue3.value)

// let suma = sliderOneValue+sliderTreeValue


UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseInOut, animations: { self.sliderValue2.setValue(Float(sliderThreeValue), animated: true)}, completion: nil)

labelResult.text = String(stringInterpolationSegment: sliderTwoValue)

label3.text = String(stringInterpolationSegment: sliderThreeValue)

}


}

}

This is not clear


@IBAction func sliderValue1Entry(_ sender: UISlider) {

textValue.text = String(Int(sender.value))

let textAmount = Int(textValue.text!)

var sliderOneValue = Int(sender.value)

var sliderTwoValue = Int(sliderValue1.value)

var sliderThreeValue = Int(sliderValue3.value)


who is the sender ? Slider1 I guess

Why do you copy its value on two but not three ?

and you don.t set the slider value anywhere with something like, for instance

SliderValue2 = sender.value


so what do you do when you slide slider 2 ?

I will explain better.

In my example I have 1 TextField (TextField1) that show the values of Slider1.

Then I have a Slider2 that shows its values on a Label1.

What I want is:

- Thumb Slider1 moves alone to its correct value place when I text a different value on TextField1

- Thumb Slider2 follows thumb Slider1 when its value change because of TextField1

- Thumb Slider2 follows thumb Slider1 when you slide the thumb of Slider1.


i use this code:


@IBOutlet weak var textValue: UITextField!

@IBOutlet weak var sliderValue1: UISlider!

@IBOutlet weak var sliderValue2: UISlider!



@IBAction func sliderValue1(_ sender: UISlider) {

textValue.text = String(Int(sender.value))


UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseInOut, animations: {

self.sliderValue2.setValue(Float(sliderValue1), animated: true)}, completion: nil)

}


What happens is that after sliding manually the thumb of Slider1. I release the thumb. And thumb Slider2 stops also but is not aligned with thumb Slider1. And I don’t understand why.

I suspect your conversion to Int may cause the difference.


could add print statements to see:


@IBAction func sliderValue1(_ sender: UISlider) {
  print("sender.value", sender.value)
  textValue.text = String(Int(sender.value))
  print("sliderValue1", sliderValue1)
  print("sliderValue2 before", sliderValue2)

  UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseInOut, animations: {
      self.sliderValue2.setValue(Float(sliderValue1), animated: true)}, completion: nil)   }

print("sliderValue2 after", sliderValue2)

Thank you again Claude31. You helped me to fix the problem.

Now it works correctly.

Great.


Don't forget to close the thread by marking the correct answer.


And some more advice:

- next time you post code, think using the formatter tool (<>) to present the code in an easier to read form, with line numbers.

- var names should start with lowerCase, to see clearly the difference with type declarations:

@IBOutlet weak var label1: UILabel!

instead of

@IBOutlet weak var Label1: UILabel!

- it is good (for maintenance and debug) to have very explicit var names.

For instance

        let alertMessage = "Falta introducir un parámetro !"
        let alertMessage2 = "Los valores introducidos deben ser superiores a 0 !"

is correct, but

       let alertMessageFaltaParam = "Falta introducir un parámetro !"
       let alertMessageValores = "Los valores introducidos deben ser superiores a 0 !"


is easier to understand


In the same way, what do you represent with:

        let perimCircValue1 = .pi*(diamAmount!)/1000
        let perimCircValue2 = Double(round(1000*perimCircValue1)/1000)

May be

        let perimCircValue = .pi*(diamAmount!)/1000
        let perimCircRoundedValue = Double(round(1000*perimCircValue1)/1000)

would be more explicit


Good continuation.