UISwitch set state - ios

I am working on an app, which has UISwitch. I want to set the switch to on/off programmatically. I tried it like so, but the switch is already turned on when setting is false... Any ideas?
#IBOutlet var switch: UISwitch!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
switch = UISwitch()
if setting == true {
switch.setOn(true, animated: false)
} else {
switch.setOn(false, animated: false)
}
}
the variable setting is not the problem.. I tested it out

I fixed it!
I just deleted the line switch = UISwitch() and now it works for me.

Related

Navigation Bar removeGestureRecognizer is not removing the Guesture

I need to add Tap Gesture on Navigation Bar or View.
I got the below solution which works perfectly fine.
But removeGestureRecognizer is not removing the gesture and it's breaking the functionality of other back buttons in other view controllers.
How to fix the issue?
var taskTodoOnBar : UITapGestureRecognizer!
override func viewWillAppear(animated: Bool)
{
navigationController?.view.addGestureRecognizer(taskTodoOnBar)
}
override func viewWillDisappear(animated: Bool)
{
navigationController?.view.removeGestureRecognizer(taskTodoOnBar)
}
Or
override func viewWillAppear(animated: Bool)
{
navigationController?.navigationBar.addGestureRecognizer(taskTodoOnBar)
}
override func viewWillDisappear(animated: Bool)
{
navigationController?.navigationBar.removeGestureRecognizer(taskTodoOnBar)
}
When I try to get gestureRecognizers count, It says nil. Then where is the gesture being added ?
override func viewWillDisappear(animated: Bool)
{
print(navigationController!.view.gestureRecognizers!.count)
print(navigationController!.navigationBar.gestureRecognizers!.count)
}
Try using this
Declared gesture as
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()
Gesture Handler
#objc func tapHandler(handler: UITapGestureRecognizer){
print("gesture Added")
}
Added in Navigation bar as
override func viewDidLoad()
{
super.viewDidLoad()
tapGesture.numberOfTapsRequired = 1
tapGesture.addTarget(self, action: #selector(VC2.tapHandler(handler:)))
self.navigationController?.view.addGestureRecognizer(tapGesture)
}
Removed as
override func viewWillDisappear(_ animated: Bool) {
for gesture in (navigationController?.view.gestureRecognizers)! {
if gesture == tapGesture {
navigationController?.view.removeGestureRecognizer(tapGesture)
print("removed")
}
}
}
Updated Answer for - gesture count prints nil
console Output :
After help from iOS Geek, I figured out that, gestureRecognizers!.count was 2 in ViewdDidLoad but was nil inside viewWillDisappear.
Then I dug more and discovered that I had written the custom code for my back button.
So in such case, we Should removeGestureRecognizer before popToViewController
So this is for all whom I wish not to make mistake like me while using the custom back button.
func backBarBtnFnc(sender: UIBarButtonItem)
{
navigationController?.navigationBar.removeGestureRecognizer(taskTodoOnBar)
// CodTdo ...
self.navigationController!.popToViewController(VC2, animated: true)
}

Skip swift ViewController main functions such as viewDidDisappear

In my code, when a view disappears, a specific action occurs. I am doing it through the viewDidDisappear() function.
I have a specific button that when is pressed it goes to another view. I was wondering in what I way I could tell ONLY the function caused by a specific button to skip the viewDidDisappear().
I perfectly know I can add a sort of 'if' statement in the viewDidDisappear() but I was wondering if there was a more efficient method.
viewDidDisappear() is a UIViewController's lifecycle callback method that's called by the environment - as far as I know there is no way to disable its calling. And I don't think there should be - as I mentioned, it is a part of UIViewController's lifecycle, not calling it would break the contract - see its documentation.
Therefore you have to (and you should) achieve what you want by using if statement.
Do something like this:
fileprivate var skipDisappearingAnimation = false
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
prepareInterfaceForDisappearing()
}
fileprivate func prepareInterfaceForDisappearing() {
guard !skipDisappearingAnimation else {
// reset each time
skipDisappearingAnimation = false
return
}
// do the stuff you normally need
}
#objc fileprivate func buttonPressed(_ sender: UIButton) {
skipDisappearingAnimation = true
// navigate forward
}
It cannot be done; you must handle the case manually with if, something like:
var shouldSkip: Bool = false
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if !shouldSkip {
// your code goes here
}
shouldSkip = false // don't forget to set should skip to false again
}
#IBAction func buttonDidTap(_ sender: Any) {
shouldSkip = true // this will avoid run your code
// your code here
}

UISwitch not working properly in swift

I have taken a UISwitch control in my new swift project. And the default state of this is set as Off from storyboard. I have bounded it as IBOutlet
#IBOutlet weak var SwitchRemFacility: UISwitch!
I have also bounded it to a method by Value change event from storyboard.
#IBAction func rememberFacilityClick(sender: AnyObject) {
print(SwitchRemFacility.on)
if SwitchRemFacility.on {
SwitchRemFacility.setOn(false, animated: true)
} else {
SwitchRemFacility.setOn(true, animated: true)
}
}
The Problem is that SwitchRemFacility.on returns always true here. I have checked by breakpoint and also I have printed it to console. Any hep will be appreciated.
Thanks in advance.
You are testing it when value is already changed. Switch will do it's on and off work by it self.
If you want to do it manually you can do like :
#IBAction func switchChangeVal(sender: AnyObject) {
let swh : UISwitch = sender as! UISwitch
if(swh.on){
swh.setOn(true, animated: true)//But it will already do it.
}
else{
swh.setOn(false, animated: true)
}
}
Actually no need of code. But if you want to condition on the on or off state then you have to do code.
For Example
#IBAction func switchChangeVal(sender: AnyObject) {
let swh : UISwitch = sender as! UISwitch
if(swh.on){
//Do the code for when switch is on
}
else{
//Do the code for when switch is off
}
}

Adapting to current screen orientation using segues

A storyboard has tow ViewControllers-s, one for Portrait orientation (VCPort for short), another for landscape (VCLand). I want the application to switch automatically to correct layout when the device is rotated.
For that purpose I have two segues portToLand from VSPort to VCLand and LandToPort in opposite direction. Then I override willRotateToScreenOrientation as the following.
For VCPort class:
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)
{
if toInterfaceOrientation.isLandscape {
switchViewController()
}
}
func switchViewController() {
performSegueWithIdentifier("portToLand", sender: self)
}
For VCLand class I have isPortrait instead of isLandscape and "landToPort" instead of "portToLand".
Everything works OK if the storyboard starts in Portrait orientation. When the storyboard starts while the device is in Landscape (e.g. with IPad Retina) VCPort still gets the control as the first ViewController in chain and willRotateToScreen doesn't come. To make the application switch to Landscape layout in this case I place the following code in viewDidLoad for VCPort class:
override func viewDidLoad() {
super.viewDidLoad()
if UIApplication.sharedApplication().statusBarOrientation.isLandscape {
switchViewController()
}
}
Tracing with debugger show thats performSegueWithIdentifier is called, but VCLand doesn't get the control, the application still shows VCPort layout! In assumption that I do it too early, I tried viewWillAppear instead of viewDidLoad - no difference.
Thanks for any comments.
Just put a short delay before switching views. And moved the code to viewWillAppear, since the orientation may change while app is in pause:
var timer : NSTimer?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let deviceOrientation = UIDevice.currentDevice().orientation
var isLandscape : Bool;
if deviceOrientation == UIDeviceOrientation.Unknown {
isLandscape = UIApplication.sharedApplication().statusBarOrientation.isLandscape
} else {
isLandscape = deviceOrientation.isLandscape
}
if isLandscape {
self.view.hidden = true
timer = NSTimer.scheduledTimerWithTimeInterval(0.05, target: self, selector: Selector("switchViewController"), userInfo: nil, repeats: false)
} else {
self.view.hidden = false
}
}
override func viewWillDisappear(animated: Bool) {
if (timer != nil) {
timer!.invalidate()
timer = nil
}
}

hidesBarsOnTap - Navigation Bar hidden/displayed event?

I would like to set the background color of a view to black when the navigation bar is hidden, and to white when the navigation bar is displayed.
The property hidesBarsOnTap is set to true in viewDidLoad. This works fine:
navigationController?.hidesBarsOnTap = true
How can I be notified when the bars are hidden and displayed?
Sorry, I made a mistake. The following code does exactly what you want. If you have a toolbar, you can set it to hide as well.
class ViewController: UIViewController {
var hidden = false {
didSet {
if let nav = navigationController {
nav.setNavigationBarHidden(hidden, animated: true)
nav.setToolbarHidden(hidden, animated: true)
view.backgroundColor = hidden ? UIColor.blackColor() : UIColor.whiteColor()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
let recognizer = UITapGestureRecognizer(target: self, action: "tap:")
view.addGestureRecognizer(recognizer)
}
func tap(recognizer: UITapGestureRecognizer) {
if recognizer.state == .Ended {
hidden = !hidden
}
}
}
since hidesBarsOnTap is of type boolean, we can easily use it to check and use it as option like in below example:
var set : Bool = navigationController?.hidesBarsOnTap //true or false
if (set){
//do what you want when set
}else{
//do what you want when it is not set
}

Resources