6

I have an UISwitch which is inside of a UITableViewCell. I have a target action assigned to switch:

[switch addTarget:self action:@selector(changeSwitchColor:) forControlEvents:UIControlEventValueChanged];

- (void)changeSwitchColor:(id)sender
{
    ...
}

The problem is that the changeSwitchColor: is called before the animation is finished, yet I want to detect when animation has finished, so I can set the thumbTintColor property without breaking the animation.

My attempt to detect the animation by using UIView setAnimationDidStopSelector: method:

[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    ...
}

But this method is not called on UISwitch finishing the animation (I'm not even sure how the animation is made internally).

How could I detect the finishing state of UISwitch?

Thanks!

Legoless
  • 10,942
  • 7
  • 48
  • 68
  • You may find your answer from the other stackoverflow answer link:http://stackoverflow.com/questions/19628310/ios7-uiswitch-its-event-valuechanged-calling-continuously-is-this-bug-or-what – Nimisha Patel Oct 02 '14 at 07:48
  • How exactly would that question answer mine? – Legoless Oct 02 '14 at 08:02
  • `UISwitch` is a NOT good class. It's hard to override or customize. I think you should override `UIControl` and make your own switch – Tony Oct 02 '14 at 09:50
  • I really wanted to avoid making my own switch, I know about `UIControl` of course. – Legoless Oct 02 '14 at 11:44

2 Answers2

9

You can use CATransaction.setCompletionBlock(_:).

addTarget(self, action: #selector(valueChanged(sender:)), for: [.valueChanged])

@objc private func valueChanged(sender: UISwitch) {
    CATransaction.setCompletionBlock { [onChange] in
        onChange?(sender.isOn)
    }
}

The documentation says the block is guaranteed to be called even if there are no animations or the animation was removed. It makes it very safe to use.

Tomáš Linhart
  • 13,509
  • 5
  • 51
  • 54
1

Tomáš answer using Swift 4:

settingsSwitch.addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged)

@objc func valueChanged(_ sender: UISwitch) {
    CATransaction.setCompletionBlock {
        //... animation just finished
    }
}
coldembrace
  • 549
  • 8
  • 19