У меня есть расширение UIButton, которое я использую для стилизации кнопок. Этот код хорошо служил мне в течение многих лет, и недавно мой телефон был обновлен до 13.5.1, и этот код работает не очень хорошо. Градиент в нормальном состоянии больше не виден. Не уверен, какая именно версия iOS нарушила это, но определенно будет> iOS 13. Работала до этого. Я подумал, что это может быть связано с темным режимом, поэтому я поставил User Interface Style = Light в свой список, это, похоже, не имеет никакого эффекта. Кажется, что даже его затемнение не влияет на внешний вид моего пользовательского интерфейса.
Что может здесь происходить и в чем конфликт с последней iOS?
#import "UIButton+CompletionBlocks.h"
#import <objc/runtime.h>
#define DEFAULT_BORDER_WIDTH 0.5f
@interface UIButton (CompletionBlocksPrivate)
@property (nonatomic) CAGradientLayer *normalLayer;
@property (nonatomic) CAGradientLayer *highlightedLayer;
@property (nonatomic) CAGradientLayer *selectedLayer;
@property (nonatomic) CAGradientLayer *selectedHighlightedLayer;
@property (nonatomic) CAGradientLayer *currentActiveLayer;
@property (nonatomic) UIColor *borderColor;
@property (nonatomic) UIColor *selectedBorderColor;
@property (nonatomic) UIColor *textColor;
@property (nonatomic) UIColor *selectedTextColor;
@property (nonatomic) BOOL styled;
@end
@implementation UIButton (CompletionBlocksPrivate)
void *_normalLayer;
void *_highlightedLayer;
void *_selectedLayer;
void *_selectedHighlightedLayer;
void *_currentActiveLayer;
void *_borderColor;
void *_selectedBorderColor;
void *_textColor;
void *_selectedTextColor;
void *_styled;
-(CAGradientLayer *) normalLayer {
return objc_getAssociatedObject(self, &_normalLayer);
}
-(void) setNormalLayer:(CAGradientLayer *)normalLayer {
objc_setAssociatedObject(self, &_normalLayer, normalLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(CAGradientLayer *) highlightedLayer {
return objc_getAssociatedObject(self, &_highlightedLayer);
}
-(void) setHighlightedLayer:(CAGradientLayer *)highlightedLayer {
objc_setAssociatedObject(self, &_highlightedLayer, highlightedLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(CAGradientLayer *) selectedLayer {
return objc_getAssociatedObject(self, &_selectedLayer);
}
-(void) setSelectedLayer:(CAGradientLayer *)selectedLayer {
objc_setAssociatedObject(self, &_selectedLayer, selectedLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(CAGradientLayer *) selectedHighlightedLayer {
return objc_getAssociatedObject(self, &_selectedHighlightedLayer);
}
-(void) setSelectedHighlightedLayer:(CAGradientLayer *)selectedHighlightedLayer {
objc_setAssociatedObject(self, &_selectedHighlightedLayer, selectedHighlightedLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(CAGradientLayer *) currentActiveLayer {
return objc_getAssociatedObject(self, &_currentActiveLayer);
}
-(void) setCurrentActiveLayer:(CAGradientLayer *)currentActiveLayer {
objc_setAssociatedObject(self, &_currentActiveLayer, currentActiveLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *) borderColor {
return objc_getAssociatedObject(self, &_borderColor);
}
-(void) setBorderColor:(UIColor *)borderColor {
objc_setAssociatedObject(self, &_borderColor, borderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *) selectedBorderColor {
return objc_getAssociatedObject(self, &_selectedBorderColor);
}
-(void) setSelectedBorderColor:(UIColor *)selectedBorderColor {
objc_setAssociatedObject(self, &_selectedBorderColor, selectedBorderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *) textColor {
return objc_getAssociatedObject(self, &_textColor);
}
-(void) setTextColor:(UIColor *)textColor {
objc_setAssociatedObject(self, &_textColor, textColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *) selectedTextColor {
return objc_getAssociatedObject(self, &_selectedTextColor);
}
-(void) setSelectedTextColor:(UIColor *)selectedTextColor {
objc_setAssociatedObject(self, &_selectedTextColor, selectedTextColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(BOOL) styled {
NSNumber *number = objc_getAssociatedObject(self, &_styled);
return number.boolValue;
}
-(void) setStyled:(BOOL)styled {
NSNumber *number = [NSNumber numberWithBool:styled];
objc_setAssociatedObject(self, &_styled, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
@implementation UIButton (CompletionBlocks)
- (UIButtonCompletionBlock )clickListener {
return objc_getAssociatedObject(self, @selector(clickListener));
}
- (void)setClickListener:(UIButtonCompletionBlock)completion{
objc_setAssociatedObject(self, @selector(clickListener), completion, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
}
-(void) buttonClicked {
self.clickListener(self);
}
-(void) styleAsWhiteButton_GreenWhenSelected {
UIColor *normalGradientStart = [UIColor colorWithRed:0xfe/255.0f green:0xfe/255.0f blue:0xfe/255.0f alpha:1.0];
UIColor *normalGradientEnd = [UIColor colorWithRed:0xf2/255.0f green:0xf2/255.0f blue:0xf2/255.0f alpha:1.0];
UIColor *highlightedGradientStart = normalGradientEnd;
UIColor *highlightedGradientEnd = normalGradientStart;
UIColor *selectedGradientStart = [UIColor colorWithRed:0xa7/255.0f green:0xb7/255.0f blue:0x4e/255.0f alpha:1.0];
UIColor *selectedGradientEnd = [UIColor colorWithRed:0x8f/255.0f green:0xa1/255.0f blue:0x40/255.0f alpha:1.0];
UIColor *selectedHighlightedGradientStart = selectedGradientEnd;
UIColor *selectedHighlightedGradientEnd = selectedGradientStart;
UIColor *borderColor = [UIColor colorWithRed:0xcc/255.0f green:0xcc/255.0f blue:0xcc/255.0f alpha:1.0];
UIColor *selectedBorderColor = [UIColor colorWithRed:0x89/255.0f green:0x9b/255.0f blue:0x3a/255.0f alpha:1.0];
UIColor *textColor = [UIColor colorWithRed:0x56/255.0f green:0x56/255.0f blue:0x56/255.0f alpha:1.0];
UIColor *selectedTextColor = [UIColor colorWithRed:0xff/255.0f green:0xff/255.0f blue:0xff/255.0f alpha:1.0];
UIColor *disabledTextColor = [UIColor colorWithRed:0xbf/255.0f green:0xbf/255.0f blue:0xbf/255.0f alpha:1.0];
[self setStyleWithTextColor:textColor selectedTextColor:selectedTextColor disabledTextColor:disabledTextColor gradientStartColor:normalGradientStart gradientEndColor:normalGradientEnd highlightedGradientStartColor:highlightedGradientStart highlightedGradientEndColor:highlightedGradientEnd selectedGradientStartColor:selectedGradientStart selectedGradientEndColor:selectedGradientEnd selectedHighlightedGradientStartColor:selectedHighlightedGradientStart selectedHighlightedGradientEndColor:selectedHighlightedGradientEnd borderColor:borderColor selectedBorderColor:selectedBorderColor];
}
-(void) styleAsFingerButton_NotRequired {
UIColor *normalGradientStart = [UIColor colorWithRed:0xef/255.0f green:0xef/255.0f blue:0xef/255.0f alpha:1.0];
UIColor *normalGradientEnd = [UIColor colorWithRed:0xdf/255.0f green:0xdf/255.0f blue:0xdf/255.0f alpha:1.0];
UIColor *highlightedGradientStart = normalGradientEnd;
UIColor *highlightedGradientEnd = normalGradientStart;
UIColor *selectedGradientStart = [UIColor colorWithRed:0xe1/255.0f green:0x53/255.0f blue:0x26/255.0f alpha:1.0];
UIColor *selectedGradientEnd = [UIColor colorWithRed:0xb4/255.0f green:0x43/255.0f blue:0x1e/255.0f alpha:1.0];
UIColor *selectedHighlightedGradientStart = selectedGradientEnd;
UIColor *selectedHighlightedGradientEnd = selectedGradientStart;
UIColor *borderColor = [UIColor colorWithRed:0xd3/255.0f green:0xd3/255.0f blue:0xd3/255.0f alpha:1.0];
UIColor *selectedBorderColor = [UIColor colorWithRed:0xc3/255.0f green:0x49/255.0f blue:0x22/255.0f alpha:1.0];
UIColor *textColor = [UIColor colorWithRed:0x56/255.0f green:0x56/255.0f blue:0x56/255.0f alpha:1.0];
UIColor *selectedTextColor = [UIColor colorWithRed:0xff/255.0f green:0xff/255.0f blue:0xff/255.0f alpha:1.0];
UIColor *disabledTextColor = [UIColor colorWithRed:0xbf/255.0f green:0xbf/255.0f blue:0xbf/255.0f alpha:1.0];
[self setStyleWithTextColor:textColor selectedTextColor:selectedTextColor disabledTextColor:disabledTextColor gradientStartColor:normalGradientStart gradientEndColor:normalGradientEnd highlightedGradientStartColor:highlightedGradientStart highlightedGradientEndColor:highlightedGradientEnd selectedGradientStartColor:selectedGradientStart selectedGradientEndColor:selectedGradientEnd selectedHighlightedGradientStartColor:selectedHighlightedGradientStart selectedHighlightedGradientEndColor:selectedHighlightedGradientEnd borderColor:borderColor selectedBorderColor:selectedBorderColor];
}
-(void) styleAsFingerButton_Required {
UIColor *normalGradientStart = [UIColor colorWithRed:0xdf/255.0f green:0xd9/255.0f blue:0xb9/255.0f alpha:1.0];
UIColor *normalGradientEnd = [UIColor colorWithRed:0xd6/255.0f green:0xc5/255.0f blue:0x9b/255.0f alpha:1.0];
UIColor *highlightedGradientStart = normalGradientEnd;
UIColor *highlightedGradientEnd = normalGradientStart;
UIColor *selectedGradientStart = [UIColor colorWithRed:0xe1/255.0f green:0x53/255.0f blue:0x26/255.0f alpha:1.0];
UIColor *selectedGradientEnd = [UIColor colorWithRed:0xb4/255.0f green:0x43/255.0f blue:0x1e/255.0f alpha:1.0];
UIColor *selectedHighlightedGradientStart = selectedGradientEnd;
UIColor *selectedHighlightedGradientEnd = selectedGradientStart;
UIColor *borderColor = [UIColor colorWithRed:0xcd/255.0f green:0xbf/255.0f blue:0x9d/255.0f alpha:1.0];
UIColor *selectedBorderColor = [UIColor colorWithRed:0xc3/255.0f green:0x49/255.0f blue:0x22/255.0f alpha:1.0];
UIColor *textColor = [UIColor colorWithRed:0x56/255.0f green:0x56/255.0f blue:0x56/255.0f alpha:1.0];
UIColor *selectedTextColor = [UIColor colorWithRed:0xff/255.0f green:0xff/255.0f blue:0xff/255.0f alpha:1.0];
UIColor *disabledTextColor = [UIColor colorWithRed:0xbf/255.0f green:0xbf/255.0f blue:0xbf/255.0f alpha:1.0];
[self setStyleWithTextColor:textColor selectedTextColor:selectedTextColor disabledTextColor:disabledTextColor gradientStartColor:normalGradientStart gradientEndColor:normalGradientEnd highlightedGradientStartColor:highlightedGradientStart highlightedGradientEndColor:highlightedGradientEnd selectedGradientStartColor:selectedGradientStart selectedGradientEndColor:selectedGradientEnd selectedHighlightedGradientStartColor:selectedHighlightedGradientStart selectedHighlightedGradientEndColor:selectedHighlightedGradientEnd borderColor:borderColor selectedBorderColor:selectedBorderColor];
}
-(void) setStyleWithTextColor:(UIColor *)textColor selectedTextColor:(UIColor *)selectedTextColor disabledTextColor:(UIColor *)disabledTextColor gradientStartColor:(UIColor *)gradientStartColor gradientEndColor:(UIColor *)gradientEndColor highlightedGradientStartColor:(UIColor *)highlightedGradientStartColor highlightedGradientEndColor:(UIColor *)highlightedGradientEndColor selectedGradientStartColor:(UIColor *)selectedGradientStartColor selectedGradientEndColor:(UIColor *)selectedGradientEndColor selectedHighlightedGradientStartColor:(UIColor *)selectedHighlightedGradientStartColor selectedHighlightedGradientEndColor:(UIColor *)selectedHighlightedGradientEndColor borderColor:(UIColor *)borderColor selectedBorderColor:(UIColor *)selectedBorderColor {
[self layoutIfNeeded];
self.borderColor = borderColor;
self.selectedBorderColor = selectedBorderColor;
self.textColor = textColor;
self.selectedTextColor = selectedTextColor;
self.layer.cornerRadius = 3.0f;
self.layer.borderWidth = DEFAULT_BORDER_WIDTH;
[self setTitleColor:disabledTextColor forState:UIControlStateDisabled];
[self setTitleColor:selectedTextColor forState:UIControlStateSelected];
// gradient
self.normalLayer = [CAGradientLayer layer];
self.normalLayer.frame = self.bounds;
self.normalLayer.colors = @[(id)gradientStartColor.CGColor,
(id)gradientEndColor.CGColor];
self.normalLayer.locations = @[@0, @1.0];
self.highlightedLayer = [CAGradientLayer layer];
self.highlightedLayer.frame = self.bounds;
self.highlightedLayer.colors = @[(id)highlightedGradientStartColor.CGColor,
(id)highlightedGradientEndColor.CGColor];
self.highlightedLayer.locations = @[@0, @1.0];
self.selectedLayer = [CAGradientLayer layer];
self.selectedLayer.frame = self.bounds;
self.selectedLayer.colors = @[(id)selectedGradientStartColor.CGColor,
(id)selectedGradientEndColor.CGColor];
self.selectedLayer.locations = @[@0, @1.0];
self.selectedHighlightedLayer = [CAGradientLayer layer];
self.selectedHighlightedLayer.frame = self.bounds;
self.selectedHighlightedLayer.colors = @[(id)selectedHighlightedGradientStartColor.CGColor,
(id)selectedHighlightedGradientEndColor.CGColor];
self.selectedHighlightedLayer.locations = @[@0, @1.0];
[self setSelected:self.selected]; // draw the button
self.clipsToBounds = YES;
self.tintColor = [UIColor clearColor];
[self addTarget:self action:@selector(buttonDown:) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:@selector(buttonUp:) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:@selector(buttonUp:) forControlEvents:UIControlEventTouchUpOutside];
[self addTarget:self action:@selector(buttonUp:) forControlEvents:UIControlEventTouchCancel];
}
-(void) buttonDown:(UIButton *)sender {
if(self.selected) {
[self makeLayerActive:self.selectedHighlightedLayer];
} else {
[self makeLayerActive:self.highlightedLayer];
}
}
-(void) buttonUp:(UIButton *)sender {
if(self.selected) {
[self makeLayerActive:self.selectedLayer];
} else {
[self makeLayerActive:self.normalLayer];
}
}
-(void) setSelected:(BOOL)selected {
[super setSelected:selected];
[self buttonUp:self]; // just draw the button up
if(selected) {
self.layer.borderColor = self.selectedBorderColor.CGColor;
[self setTitleColor:self.selectedTextColor forState:UIControlStateNormal];
[self setTitleColor:self.selectedTextColor forState:UIControlStateHighlighted];
self.titleLabel.textColor = self.selectedTextColor;
} else {
self.layer.borderColor = self.borderColor.CGColor;
[self setTitleColor:self.textColor forState:UIControlStateNormal];
[self setTitleColor:self.textColor forState:UIControlStateHighlighted];
self.titleLabel.textColor = self.textColor;
}
}
-(void) setBorderedSelected:(BOOL)borderedSelected {
if(borderedSelected) {
self.layer.borderWidth = 2.5f;
self.layer.borderColor = [UIColor blackColor].CGColor;
} else {
self.layer.borderWidth = DEFAULT_BORDER_WIDTH;
}
}
-(void) makeLayerActive:(CAGradientLayer *)layer {
[self.currentActiveLayer removeFromSuperlayer];
[self.layer insertSublayer:layer atIndex:0];
self.currentActiveLayer = layer;
}
@end