357

I have added multiple target-action-forControlEvents: to a UIButton. I'd like to remove all of these in one go without deallocating anything. I will then set new targets.

Is this possible and how do I go about it?

Juan Boero
  • 6,281
  • 1
  • 44
  • 62
Ken
  • 30,811
  • 34
  • 116
  • 155

6 Answers6

871

Call removeTarget:action:forControlEvents:, pass nil for the target, NULL for action, and use a control mask that sets all bits (UIControlEventAllEvents).

Objective-C

[someControl removeTarget:nil 
                   action:NULL 
         forControlEvents:UIControlEventAllEvents];

Swift 2

button.removeTarget(nil, action: nil, forControlEvents: .AllEvents)

Swift 3 or higher

button.removeTarget(nil, action: nil, for: .allEvents)
Ved Sharma
  • 701
  • 1
  • 6
  • 20
progrmr
  • 75,956
  • 16
  • 112
  • 147
  • 4
    Thanks for the tip! Here's the full link I think (ie. to the section): "http://developer.apple.com/iphone/library/documentation/uikit/reference/UIControl_Class/Reference/Reference.html#//apple_ref/occ/instm/UIControl/removeTarget:action:forControlEvents:" – Ken Jul 27 '10 at 06:36
  • 1
    progrmr's suggestion works of course. To add to the answer here is a code snippet like the one I needed: [button removeTarget:nil action:NULL forControlEvents:UIControlEventTouchUpInside]; – Ken Jul 27 '10 at 06:48
  • 6
    Aside: the -allTargets instance method returns an NSSet of all the instance's targets (nil if none). – Ken Jul 28 '10 at 00:26
  • 3
    Perfect! exactly what i was looking for:D – Totumus Maximus Oct 18 '11 at 07:35
  • 1
    Updated with Swift 2 and 3, as there are competing answers with exactly the same answer, differing only in language. – Peter DeWeese Aug 29 '17 at 19:31
  • 1
    The link has changed to: https://developer.apple.com/documentation/uikit/uicontrol/1618248-removetarget – Panayotis Dec 22 '18 at 00:25
96

@progrmr's answer in Swift 2:

button.removeTarget(nil, action: nil, forControlEvents: .AllEvents)

and Swift 3:

button.removeTarget(nil, action: nil, for: .allEvents)

Note: Swift doesn't have NULL, so I tested replacing it with nil and it seems to work fine.

Hlung
  • 13,850
  • 6
  • 71
  • 90
  • 5
    For Swift 3: ".AllEvents" is now ".allEvents" (with a lowercase 'a'): `removeTarget(nil, action: nil, for: .allEvents)` – Sasho Sep 16 '16 at 05:39
  • Regarding your NOTE: Actually, I believe you could pass either `nil` or `NULL` to **both** the first and second arguments in Objective-C too, and it will work. I believe both are defined as `(void*) 0` (or at the very least, evaluate as equals). – Nicolas Miari Nov 25 '16 at 05:16
  • @Sasho I would love to see some statistics on how much source files sizes go down (on average) when upgrading to Swift 3 :-) (due to the new method/argument naming rules). – Nicolas Miari Nov 25 '16 at 05:18
  • Since this is the same answer in a different language, and the language is not tagged in this question, it should be an edit to @progrmr's answer. – Peter DeWeese Aug 29 '17 at 19:24
9

Swift 3, 4, 5:

btnCancel.removeTarget(nil, action: nil, forControlEvents: UIControlEvents.AllEvents)
Mohit Kumar
  • 2,898
  • 3
  • 21
  • 34
Iya
  • 1,888
  • 19
  • 12
8

Swift 2:

actionButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)

Swift 3 & 4:

actionButton.removeTarget(nil, action: nil, for: .allEvents)

Objective-C:

[actionButton removeTarget: nil action: NULL forControlEvents: UIControlEventAllEvents];
Tim Langner
  • 357
  • 3
  • 16
Riajur Rahman
  • 1,976
  • 19
  • 28
4
- removeTarget:action:forControlEvents:

This method stops the delivery of events to the specified target object.

  1. Specifying a valid object in the target parameter, this method stops the delivery of the specified events to all action methods associated with that object.

  2. Specifying nil for the target parameter, this method prevents the delivery of those events to all action methods of all target objects

    objective-c:

    [_myButton removeTarget:  //any validObject (or) nil
                  action:nil
        forControlEvents:UIControlEventAllEvents]; 
    

    swift:

    myButton.removeTarget(*validObject or nil*, action:nil, forControlEvents:UIControlEvents.AllEvents)
    

For more details https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIControl_Class/index.html#//apple_ref/occ/instm/UIControl/removeTarget:action:forControlEvents:

UdayM
  • 1,725
  • 16
  • 34
0

you can change the selector if it is conditional. see below example

you can remove all the targets first, then choose the selector and add it.

rateButton.removeTarget(nil, action: nil, for: .allEvents)

    let action = interview.isRated ? #selector(viewTapped(_:)) : #selector(rateTapped(_:))
            
    rateButton.addTarget(self, action: action, for: .touchUpInside)
Divesh singh
  • 409
  • 4
  • 12