Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion TORoundedButton/TORoundedButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
NS_ASSUME_NONNULL_BEGIN

@class TORoundedButton;
@class UICornerConfiguration;

NS_SWIFT_NAME(RoundedButtonDelegate)
@protocol TORoundedButtonDelegate <NSObject>
Expand All @@ -41,7 +42,12 @@ IB_DESIGNABLE @interface TORoundedButton : UIControl
/// A delegate object that can receive tap events from this button.
@property (nonatomic, weak) id<TORoundedButtonDelegate> delegate;

/// The radius of the corners of this button (Default is 12.0f).
/// The corner-rounding behaviour of the button's boundaries.
/// On iOS 26 and above, this is the `.capsule` preset by default.
@property (nonatomic, strong, nullable) UICornerConfiguration *cornerConfiguration API_AVAILABLE(ios(26.0));

/// The radius of the corners of this button.
/// (Default is 12.0f on iOS 18 and below. For iOS 26.0, changing this property will update `cornerConfiguration`.)
@property (nonatomic, assign) IBInspectable CGFloat cornerRadius;

/// The hosting container that manages all of the foreground views in this button.
Expand Down
38 changes: 28 additions & 10 deletions TORoundedButton/TORoundedButton.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ @implementation TORoundedButton {
#pragma mark - View Creation -

- (instancetype)init {
if (self = [self initWithFrame:(CGRect){0,0, 288.0f, 50.0f}]) { }
if (self = [self initWithFrame:(CGRect){0,0, 288.0f, 44.0f}]) { }
return self;
}

Expand Down Expand Up @@ -86,7 +86,7 @@ - (instancetype)initWithContentView:(__kindof UIView *)contentView {
}

- (instancetype)initWithText:(NSString *)text {
if (self = [super initWithFrame:(CGRect){0,0, 288.0f, 50.0f}]) {
if (self = [super initWithFrame:(CGRect){0,0, 288.0f, 44.0f}]) {
_contentView = [UIView new];
[self _roundedButtonCommonInit];
[self _makeTitleLabelIfNeeded];
Expand All @@ -99,7 +99,6 @@ - (instancetype)initWithText:(NSString *)text {

- (void)_roundedButtonCommonInit TOROUNDEDBUTTON_OBJC_DIRECT {
// Default properties (Make sure they're not overriding IB)
_cornerRadius = (_cornerRadius > FLT_EPSILON) ?: 12.0f;
_tappedTextAlpha = (_tappedTextAlpha > FLT_EPSILON) ?: 1.0f;
_tapAnimationDuration = (_tapAnimationDuration > FLT_EPSILON) ?: 0.4f;
_tappedButtonScale = (_tappedButtonScale > FLT_EPSILON) ?: 0.97f;
Expand Down Expand Up @@ -133,6 +132,13 @@ - (void)_roundedButtonCommonInit TOROUNDEDBUTTON_OBJC_DIRECT {
[self addTarget:self action:@selector(_didTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:@selector(_didDragOutside) forControlEvents:UIControlEventTouchDragExit|UIControlEventTouchCancel];
[self addTarget:self action:@selector(_didDragInside) forControlEvents:UIControlEventTouchDragEnter];

// Set the corner radius depending on app version
if (@available(iOS 26.0, *)) {
self.cornerConfiguration = [UICornerConfiguration capsuleConfiguration];
} else {
_cornerRadius = (_cornerRadius > FLT_EPSILON) ?: 12.0f;
}
}

- (void)_makeTitleLabelIfNeeded TOROUNDEDBUTTON_OBJC_DIRECT {
Expand Down Expand Up @@ -166,7 +172,6 @@ - (UIView *)_makeBackgroundViewWithBlur:(BOOL)withBlur TOROUNDEDBUTTON_OBJC_DIRE
}
backgroundView.frame = self.bounds;
backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
backgroundView.layer.cornerRadius = _cornerRadius;
#ifdef __IPHONE_13_0
if (@available(iOS 13.0, *)) { backgroundView.layer.cornerCurve = kCACornerCurveContinuous; }
#endif
Expand Down Expand Up @@ -200,7 +205,6 @@ - (void)layoutSubviews {

// Lay out the title label
if (!_titleLabel) { return; }

[_titleLabel sizeToFit];
_titleLabel.center = (CGPoint){
.x = CGRectGetMidX(_contentView.bounds),
Expand Down Expand Up @@ -271,7 +275,7 @@ - (UIColor *)_labelBackgroundColor TOROUNDEDBUTTON_OBJC_DIRECT {
if (_isTapped || _isTranslucent) { return [UIColor clearColor]; }

// Return clear if the tint color isn't opaque
BOOL isClear = CGColorGetAlpha(self.tintColor.CGColor) < (1.0f - FLT_EPSILON);
const BOOL isClear = CGColorGetAlpha(self.tintColor.CGColor) < (1.0f - FLT_EPSILON);
return isClear ? [UIColor clearColor] : self.tintColor;
}

Expand Down Expand Up @@ -361,7 +365,7 @@ - (void)_setBackgroundColorTappedAnimated:(BOOL)animated TOROUNDEDBUTTON_OBJC_DI
- (void)_setLabelAlphaTappedAnimated:(BOOL)animated TOROUNDEDBUTTON_OBJC_DIRECT {
if (_tappedTextAlpha > 1.0f - FLT_EPSILON) { return; }

CGFloat alpha = _isTapped ? _tappedTextAlpha : 1.0f;
const CGFloat alpha = _isTapped ? _tappedTextAlpha : 1.0f;

// Animate the alpha value of the label
void (^animationBlock)(void) = ^{
Expand Down Expand Up @@ -392,7 +396,7 @@ - (void)_setLabelAlphaTappedAnimated:(BOOL)animated TOROUNDEDBUTTON_OBJC_DIRECT
- (void)_setButtonScaledTappedAnimated:(BOOL)animated TOROUNDEDBUTTON_OBJC_DIRECT {
if (_tappedButtonScale < FLT_EPSILON) { return; }

CGFloat scale = _isTapped ? _tappedButtonScale : 1.0f;
const CGFloat scale = _isTapped ? _tappedButtonScale : 1.0f;

// Animate the alpha value of the label
void (^animationBlock)(void) = ^{
Expand Down Expand Up @@ -511,12 +515,26 @@ - (void)setCornerRadius:(CGFloat)cornerRadius {
if (fabs(cornerRadius - _cornerRadius) < FLT_EPSILON) {
return;
}

_cornerRadius = cornerRadius;
_backgroundView.layer.cornerRadius = _cornerRadius;

if (@available(iOS 26.0, *)) {
UICornerRadius *const radius = [UICornerRadius fixedRadius:_cornerRadius];
_backgroundView.cornerConfiguration = [UICornerConfiguration configurationWithUniformRadius:radius];
} else {
_backgroundView.layer.cornerRadius = _cornerRadius;
}
[self setNeedsLayout];
}

- (void)setCornerConfiguration:(UICornerConfiguration *)cornerConfiguration {
_backgroundView.cornerConfiguration = cornerConfiguration;
}

- (UICornerConfiguration *)cornerConfiguration {
return _backgroundView.cornerConfiguration;
}

- (void)setIsTranslucent:(BOOL)isTranslucent {
if (_isTranslucent == isTranslucent) {
return;
Expand Down
Loading