How to disable UISlider? - ios

I've seen answers about this but no actual code explaining how to, I'm new to swift so really confused on how to perform this simple task.
I have a UISlider However I want to disable the sliders function when an if statement is true.
I current have a UISlider with an if statement but can't workout how to disable it.
#IBAction func radiusSlider(sender: UISlider) {
if location == false {
//Disable Slider
} else {
radiusData.radiusValue = Double(sender.value)
radiusLabel.text = "Radius: \(sender.value)km"
NSNotificationCenter.defaultCenter().postNotificationName(radiusValue, object: self)
}
}
Or would this be in within the viewDidLoad? If so how?

Set the UISlider's enabled property to false.
#IBAction func radiusSlider(sender: UISlider) {
if location == false {
sender.enabled = false
} else {
radiusData.radiusValue = Double(sender.value)
radiusLabel.text = "Radius: \(sender.value)km"
NSNotificationCenter.defaultCenter().postNotificationName(radiusValue, object: self)
}
}
If you want to enable/disable your slider in other functions of your view controller, you will need to make an IBOutlet property for your slider.

Related

Why are animated calls of UIView.isHidden = false compounded?

As you can see I'm having trouble formulating the question. Let me try to explain:
I'm using a search bar in my swift ios app. In order to get a desired animation effect I put it in a vertical stack view and then animate its isHidden property. This way search bar pushes down other children of the stack view as it animates in or pulls them up as it animates out. So far so good.
I've noticed a behavior that I think is strange. Could be a bug or could be me not understanding how things work. Basically if I call search bar hiding method x times in a row I need to call search bar showing method x times before it would show. I'd expect to have to make just one call to show search bar regardless of how many times I called hiding method. The issue doesn't exist other way around: if I call search bar showing code x times I only need to call hiding method once for it to go away. This doesn't happen if I set isHidden without animating it...
Here's a sample code and a video of the issue. I'd appreciate it if someone would help me understand this behavior.
class ViewController: UIViewController {
#IBOutlet weak var searchBar: UISearchBar! {
didSet {
searchBar.isHidden = true
}
}
#IBAction func showAction(_ sender: UIButton) {
expandSearch()
}
#IBAction func hideAction(_ sender: UIButton) {
collapseSearch()
}
private func expandSearch() {
UIView.animate(withDuration: 0.3){
self.searchBar.isHidden = false
}
}
private func collapseSearch() {
UIView.animate(withDuration: 0.3){
self.searchBar.isHidden = true
}
searchBar.resignFirstResponder()
}
}
You should not call an asynchronous animation of searchbar x times, instead of I suggest you to keep its state in variable, something like isSearchBarHidden,
and check it before show/hide search bar. You could use just one method with such signature showSearchBar(show: Bool) and setting this variable there.
#IBAction func showAction(_ sender: UIButton) {
showSearchBar(true)
}
#IBAction func hideAction(_ sender: UIButton) {
showSearchBar(false)
}
private
func showSearchBar(_ show: Bool) {
guard isSearchBarHidden != show else {
return
}
UIView.animate(withDuration: 0.3, animations: {
self.searchBar.isHidden = show
}) {
self.isSearchBarHidden = show
if !show && searchBar.isFerstResponder {
searchBar.resignFirstResponder
}
}
}
private
var isSearchBarHidden: Bool = true
Also it is a good practice to check if your textView/textField/searchBar isFirstResponder before call resignFirstResponder.
Hope it will help. Good luck!

Can we make 1 UIButton for 2 action with swift?

i want to make 2 action for a button like that.
selected and deselected action for 1 button.
#IBAction func btntouch(sender: UIButton) {
if firsttouch
{
print bla bla
change button to selected style. maybe background color.
}
else
{
}
}
how can i do that?
In case you need to split two button statuses - like ON and OFF, try this:
var buttonSwitched : Bool = false
#IBAction func btntouch(sender: UIButton) {
//this line toggle your button status variable
//if true, it goes to false, and vice versa
self.buttonSwitched = !self.buttonSwitched
if self.buttonSwitched
{
//your UI styling
}
else
{
//your opposite UI styling
}
}
Create 2 IBActions:
#IBAction func touchDown(_ sender: AnyObject) {
print("down")
}
#IBAction func touchUp(_ sender: AnyObject) {
print("up")
}
When connecting the first one, make sure the event is set to touchDown. For the second one, make sure it is set to touchUpInside
Yes, you can. Depending on your requirements, you could store the current state of the button in the view controller or in the model.
If the visual change caused by the first touch needs to be persisted across opening and closing of your view controller, store the value indicating the change in the model; if you need to reset the visuals when the view controller shows, store the value in the view controller itself:
var firstTouch = true
#IBAction func btntouch(sender: UIButton) {
if firstTouch {
firstTouch = false
...
} else {
...
}
}

iOS: Swift: UISlider editingDidEnd not being called

I've set up a function for editing did end with a slider, but it doesn't look like it's being called. I've thrown a print statement into it, and a breakpoint. Is there something else that needs to be done to trigger a function when my user lets go of the slider?
#IBAction func sliderEditingDidEnd(sender: UISlider) {
print("did end");
}
Use the event "Value Changed". If you just want updates for the final value, alter UISlider.continuous
var slider = UISlider()
slider.continuous = false
//add slider to view
#IBAction func valueChanged(sender: UISlider) {
println("Value changed.")
}
//prints "Value changed." once upon releasing slider.
If the slider needs to be continuous, you can implement an event for UIControlEvent.TouchUpInside.
Or in code:
override func viewDidLoad() {
super.viewDidLoad()
mySlider.addTarget(self, action: "userReleasedSlider:", forControlEvents: UIControlEvents.TouchUpInside)
// Do any additional setup after loading the view, typically from a nib.
}
func userReleasedSlider(slider: UISlider) {
print("User released slider.")
}
I think what you are trying to do is to get the notification when the value is changed. Then you have to set event to 'Value Changed' not 'Editing Did End'.
If you set both Touch Up Inside and Touch Up Outside to point to your #IBAction then you can get the function to fire when the user finishes sliding and keep the slider as continuous.

Prevent simultaneously tapping on views

I have many views, and I want the behaviour that when I tap at the first view, other views interaction will be disabled until the task finish.
Now, my code looks like this.
private var lock = false
#IBAction func firstViewTapped(sender: UITapGestureRecognizer) {
if lock{
return
}
lock = true
doSomeTask{ error in
println("finish 1!!")
self.lock = false
}
}
#IBAction func secondViewTapped(sender: UITapGestureRecognizer) {
if lock{
return
}
lock = true
doSomeTask{ error in
println("finish 2!!")
self.lock = false
}
}
I am wondering. Is there another elegant way to do this ?
You can use self.view.userInteractionEnabled = false and self.view.userInteractionEnabled = true to lock and unlock it. Be careful you app may be unresponsive if you don't unlock the view properly.

Disable an IBAction

I've created an IBAction from a button on the storyboard. After it is clicked, I want to disable it so its no longer functional. How can I do this?
#IBAction func b1(sender: AnyObject) {
displayLabel(1)
}
Create an outlet for your button and set its enabled property to false in your b1 func. Say your outlet is "button1":
button1.enabled = false
#Mike Taverne is right about disabling button. But from the line
button.enabled = false
will make button dark greyed out. And user clearly see that it is not tappable or clickable.
But if we use this line:
button.userInteractionEnabled = false
Then button UI will not change and user thinks that it is tappable. But related action event will not called.
In both case action will not called but the look of button will matter here.
Code will suppose to be like:
#IBAction func b1(sender: AnyObject) {
var view = UIView()
view = sender as UIView
view.userInteractionEnabled = false
}
You will get the button instance in that function as sender (AnyObject).
You need to convert it to UIButton and set it's userInteractionEnabled or enabled property to false.
#IBAction func b1(sender: AnyObject)
{
displayLabel(1)
var button = sender as UIButton;
button.userInteractionEnabled = false;
}
Alternatively, you can do it using:
#IBAction func b1(sender: UIButton)
{
displayLabel(1)
sender.enabled = false;
}

Resources