6

I'm creating a custom UI-Element and want to trigger a custom UIControlEvent. I already found out, that there is a range ApplicationReserved.

Sadly this doesn't work, because it "does not conform to protocol 'RawRepresentable':

enum MyCustomEvents : UIControlEvents{
  case Increase = 0x01000000
  case Decrease = 0x02000000
}

Two questions:
1) Is this the right approach for custom events?
2) How can I define custom events correctly?

Thanks!

hendra
  • 2,531
  • 5
  • 22
  • 34

3 Answers3

15

Since what you want is just another UIControlEvent, you can use (as you were before) the range defined by .applicationReserved as a free space for you to use. Though, a more correct and easy to use way to do this would be:

(Swift 3.0):

extension UIControlEvents {
    static var increased: UIControlEvents { return UIControlEvents(rawValue: 0b0001 << 24) }
    static var decreased: UIControlEvents { return UIControlEvents(rawValue: 0b0010 << 24) }
}

In this way you can easily use this definitions everywhere events are supposed to be used, also with the convenience of type inference (e.g. sendActions(for: [.valueChanged, .increased])).

The declaration also looks cleaner to me as being these bits it's easier to see that they're disjoint by using a shift. Since .applicationReserved is defined as 0b1111 << 24, it's more definite which parts of it you're using.

These can be public if needed, and there's not much difference between having computed vars like here or just assigning let constants.

DeFrenZ
  • 2,172
  • 1
  • 20
  • 19
6

Since UIControlEvents are created as a struct of OptionSetType in Swift 2.0, you can create custom UIControlEvents in the same way.

For your question, it will be

struct MyCustomEvents : OptionSetType{
    let rawValue : UInt

    static let Increase = MyCustomEvents(rawValue: 0x01000000)
    static let Decrease = MyCustomEvents(rawValue: 0x02000000)
}

For adding a target/action to this custom UIControlEvent, you need to cast this as a UIControl Event.

let controlEvent : UIControlEvents = UIControlEvents.init(rawValue: MyCustomEvents.Increase.rawValue)
sliderControl.addTarget(self, action: "increaseAction:", forControlEvents: controlEvent)
UditS
  • 1,936
  • 17
  • 37
  • For details on NS_Options style bitmask enumerations, checkout this answer : http://stackoverflow.com/questions/24066170/how-to-create-ns-options-style-bitmask-enumerations-in-swift – UditS Oct 08 '15 at 07:36
  • @user3726405 : Please accept the answer if it helped you, or let me know in case you are facing any issues – UditS Oct 12 '15 at 07:57
  • this works! Extending from OptionsSetType made the difference. Thanks – hendra Oct 15 '15 at 09:55
  • Can you write please how can you trigger this custom "Increase" action from inside a custom class? – RobbeR Jan 04 '16 at 21:35
  • @UditS, how do you know which the `rawValue` values are fine for use? Might the `0x01000000` already stand for some event? – igrek Jun 21 '18 at 15:28
  • ahh, found the docs.. so answering my own question: `UIControlEventApplicationReserved = 0x0F000000,` – igrek Jun 21 '18 at 15:31
  • so that appears to be, egh 15 events – igrek Jun 21 '18 at 15:32
1

Swift 5

the UIControlEvents has been renamed to UIControl.Event


extension UIControl.Event {

    static var dismissed: UIControl.Event = UIControl.Event(rawValue: 0b0010 << 24)
}
Fitsyu
  • 860
  • 11
  • 19