How to create a custom UIControlEvent in Swift?
Asked Answered
L

3

7

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!

Lorentz answered 28/9, 2015 at 9:35 Comment(0)
N
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)
Neck answered 8/10, 2015 at 7:35 Comment(7)
For details on NS_Options style bitmask enumerations, checkout this answer : #24066670Neck
@user3726405 : Please accept the answer if it helped you, or let me know in case you are facing any issuesNeck
this works! Extending from OptionsSetType made the difference. ThanksLorentz
Can you write please how can you trigger this custom "Increase" action from inside a custom class?Doall
@UditS, how do you know which the rawValue values are fine for use? Might the 0x01000000 already stand for some event?Etherealize
ahh, found the docs.. so answering my own question: UIControlEventApplicationReserved = 0x0F000000,Etherealize
so that appears to be, egh 15 eventsEtherealize
I
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.

Invertebrate answered 29/1, 2017 at 17:1 Comment(1)
Is there way to set these control events available in interface builder?Pejoration
N
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)
Neck answered 8/10, 2015 at 7:35 Comment(7)
For details on NS_Options style bitmask enumerations, checkout this answer : #24066670Neck
@user3726405 : Please accept the answer if it helped you, or let me know in case you are facing any issuesNeck
this works! Extending from OptionsSetType made the difference. ThanksLorentz
Can you write please how can you trigger this custom "Increase" action from inside a custom class?Doall
@UditS, how do you know which the rawValue values are fine for use? Might the 0x01000000 already stand for some event?Etherealize
ahh, found the docs.. so answering my own question: UIControlEventApplicationReserved = 0x0F000000,Etherealize
so that appears to be, egh 15 eventsEtherealize
P
1

Swift 5

the UIControlEvents has been renamed to UIControl.Event


extension UIControl.Event {

    static var dismissed: UIControl.Event = UIControl.Event(rawValue: 0b0010 << 24)
}
Pich answered 13/6, 2019 at 16:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.