Super call in overridden class method

I want to add a new custom UIButtonTypeto the class UIButtonthrough this category:

enum {
    UIButtonTypeMatteWhiteBordered = 0x100
};

@interface UIButton (Custom)

+ (id)buttonWithType:(UIButtonType)buttonType;

@end

Is there any way to implement the implementation of this overridden method super?

+ (id)buttonWithType:(UIButtonType)buttonType {
    return [super buttonWithType:buttonType];
}

The above code is invalid because it superrefers to UIControlin this context.

+3
source share
3 answers

, , , , , , .

UIButton, :

enum {
    UIButtonTypeMatteWhiteBordered = 0x100
};

@interface MyCustomButton : UIButton {}

@end

@implementation MyCustomButton 

+ (id)buttonWithType:(UIButtonType)buttonType {
    return [super buttonWithType:buttonType]; //super here refers to UIButton
}

@end
+3

:

#import <objc/runtime.h>

@implementation UIButton(Custom)

// At runtime this method will be called as buttonWithType:
+ (id)customButtonWithType:(UIButtonType)buttonType 
{
    // ---Add in custom code here---

    // This line at runtime does not go into an infinite loop
    // because it will call the real method instead of ours. 
    return [self customButtonWithType:buttonType];
}

// Swaps our custom implementation with the default one
// +load is called when a class is loaded into the system
+ (void) load
{
    SEL origSel = @selector(buttonWithType:);

    SEL newSel = @selector(customButtonWithType:);

    Class buttonClass = [UIButton class];

    Method origMethod = class_getInstanceMethod(buttonClass, origSel);
    Method newMethod = class_getInstanceMethod(buttonClass, newSel);
    method_exchangeImplementations(origMethod, newMethod);
}

, , , UIButton, . , + , , + load .

UIButton.

. , , .

+5

, , . Apple , , , , , - , , .

, , , UIButton, , , . UIButton - [UIButton buttonWithType:]. , , ():

@implementation MyCustomButton 

+ (id)buttonWithType:(UIButtonType)buttonType {
  return [super buttonWithType:buttonType]; //super here refers to UIButton
}

@end

, , [MyCustomButton buttonWithType:], - UIButton, MyCustomButton. Apple UIButton init, UIButton.

- , UIView, , UIButton .

- :

@interface MyButton : UIView {}

- (void)buttonTapped;

@end

@implementation MyButton

-(id)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = self.bounds;
    [button addTarget:self action:@selector(buttonTapped)
     forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:button];
  }
  return self;
}

- (void)buttonTapped {
  // Respond to a button tap.
}

@end

If you want the button to perform different actions depending on more complex user interactions, you can make more calls [UIButton addTarget:action:forControlEvents:]for different control events.

Link: Apple UIButton class reference

+3
source

Source: https://habr.com/ru/post/1778349/


All Articles