Skip to content

Commit 54e35ba

Browse files
authored
Merge pull request #53 from TimOliver/ios-26
Add iOS 26 style corner rounding
2 parents 3f42156 + f05ca70 commit 54e35ba

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

TORoundedButton/TORoundedButton.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
NS_ASSUME_NONNULL_BEGIN
2626

2727
@class TORoundedButton;
28+
@class UICornerConfiguration;
2829

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

44-
/// The radius of the corners of this button (Default is 12.0f).
45+
/// The corner-rounding behaviour of the button's boundaries.
46+
/// On iOS 26 and above, this is the `.capsule` preset by default.
47+
@property (nonatomic, strong, nullable) UICornerConfiguration *cornerConfiguration API_AVAILABLE(ios(26.0));
48+
49+
/// The radius of the corners of this button.
50+
/// (Default is 12.0f on iOS 18 and below. For iOS 26.0, changing this property will update `cornerConfiguration`.)
4551
@property (nonatomic, assign) IBInspectable CGFloat cornerRadius;
4652

4753
/// The hosting container that manages all of the foreground views in this button.

TORoundedButton/TORoundedButton.m

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ @implementation TORoundedButton {
5555
#pragma mark - View Creation -
5656

5757
- (instancetype)init {
58-
if (self = [self initWithFrame:(CGRect){0,0, 288.0f, 50.0f}]) { }
58+
if (self = [self initWithFrame:(CGRect){0,0, 288.0f, 44.0f}]) { }
5959
return self;
6060
}
6161

@@ -86,7 +86,7 @@ - (instancetype)initWithContentView:(__kindof UIView *)contentView {
8686
}
8787

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

100100
- (void)_roundedButtonCommonInit TOROUNDEDBUTTON_OBJC_DIRECT {
101101
// Default properties (Make sure they're not overriding IB)
102-
_cornerRadius = (_cornerRadius > FLT_EPSILON) ?: 12.0f;
103102
_tappedTextAlpha = (_tappedTextAlpha > FLT_EPSILON) ?: 1.0f;
104103
_tapAnimationDuration = (_tapAnimationDuration > FLT_EPSILON) ?: 0.4f;
105104
_tappedButtonScale = (_tappedButtonScale > FLT_EPSILON) ?: 0.97f;
@@ -133,6 +132,13 @@ - (void)_roundedButtonCommonInit TOROUNDEDBUTTON_OBJC_DIRECT {
133132
[self addTarget:self action:@selector(_didTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
134133
[self addTarget:self action:@selector(_didDragOutside) forControlEvents:UIControlEventTouchDragExit|UIControlEventTouchCancel];
135134
[self addTarget:self action:@selector(_didDragInside) forControlEvents:UIControlEventTouchDragEnter];
135+
136+
// Set the corner radius depending on app version
137+
if (@available(iOS 26.0, *)) {
138+
self.cornerConfiguration = [UICornerConfiguration capsuleConfiguration];
139+
} else {
140+
_cornerRadius = (_cornerRadius > FLT_EPSILON) ?: 12.0f;
141+
}
136142
}
137143

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

201206
// Lay out the title label
202207
if (!_titleLabel) { return; }
203-
204208
[_titleLabel sizeToFit];
205209
_titleLabel.center = (CGPoint){
206210
.x = CGRectGetMidX(_contentView.bounds),
@@ -271,7 +275,7 @@ - (UIColor *)_labelBackgroundColor TOROUNDEDBUTTON_OBJC_DIRECT {
271275
if (_isTapped || _isTranslucent) { return [UIColor clearColor]; }
272276

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

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

364-
CGFloat alpha = _isTapped ? _tappedTextAlpha : 1.0f;
368+
const CGFloat alpha = _isTapped ? _tappedTextAlpha : 1.0f;
365369

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

395-
CGFloat scale = _isTapped ? _tappedButtonScale : 1.0f;
399+
const CGFloat scale = _isTapped ? _tappedButtonScale : 1.0f;
396400

397401
// Animate the alpha value of the label
398402
void (^animationBlock)(void) = ^{
@@ -511,12 +515,26 @@ - (void)setCornerRadius:(CGFloat)cornerRadius {
511515
if (fabs(cornerRadius - _cornerRadius) < FLT_EPSILON) {
512516
return;
513517
}
514-
518+
515519
_cornerRadius = cornerRadius;
516-
_backgroundView.layer.cornerRadius = _cornerRadius;
520+
521+
if (@available(iOS 26.0, *)) {
522+
UICornerRadius *const radius = [UICornerRadius fixedRadius:_cornerRadius];
523+
_backgroundView.cornerConfiguration = [UICornerConfiguration configurationWithUniformRadius:radius];
524+
} else {
525+
_backgroundView.layer.cornerRadius = _cornerRadius;
526+
}
517527
[self setNeedsLayout];
518528
}
519529

530+
- (void)setCornerConfiguration:(UICornerConfiguration *)cornerConfiguration {
531+
_backgroundView.cornerConfiguration = cornerConfiguration;
532+
}
533+
534+
- (UICornerConfiguration *)cornerConfiguration {
535+
return _backgroundView.cornerConfiguration;
536+
}
537+
520538
- (void)setIsTranslucent:(BOOL)isTranslucent {
521539
if (_isTranslucent == isTranslucent) {
522540
return;

0 commit comments

Comments
 (0)