From f7c7c30b43d251624a6f7f8c1f3a34392942733b Mon Sep 17 00:00:00 2001 From: Tim Oliver Date: Mon, 3 Nov 2025 15:35:39 +0900 Subject: [PATCH 1/3] Clean up inconsistent rounding on iOS --- TOSegmentedControl/TOSegmentedControl.m | 27 +++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/TOSegmentedControl/TOSegmentedControl.m b/TOSegmentedControl/TOSegmentedControl.m index c7ca858..f77b1a7 100644 --- a/TOSegmentedControl/TOSegmentedControl.m +++ b/TOSegmentedControl/TOSegmentedControl.m @@ -140,21 +140,12 @@ - (void)commonInit { UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.trackView.layer.masksToBounds = YES; self.trackView.userInteractionEnabled = NO; -#ifdef __IPHONE_13_0 - if (@available(iOS 13.0, *)) { - self.trackView.layer.cornerCurve = kCACornerCurveContinuous; - } -#endif + [self addSubview:self.trackView]; // Create thumb view self.thumbView = [[UIView alloc] initWithFrame:CGRectMake(2.0f, 2.0f, 100.0f, 28.0f)]; self.thumbView.layer.shadowColor = [UIColor blackColor].CGColor; -#ifdef __IPHONE_13_0 - if (@available(iOS 13.0, *)) { - self.thumbView.layer.cornerCurve = kCACornerCurveContinuous; - } -#endif [self.trackView addSubview:self.thumbView]; // Create list for managing each item @@ -1272,15 +1263,25 @@ - (void)setCornerRadius:(CGFloat)cornerRadius { [self _updateCornerRadius]; } +- (BOOL)_isCapsuleShape { + return _cornerRadius == TOSegmentendControlCapsuleCornerRadius; +} + - (CGFloat)_cornerRadiusValue { - const BOOL isCapsuleShape = _cornerRadius == TOSegmentendControlCapsuleCornerRadius; - return isCapsuleShape ? CGRectGetHeight(self.trackView.frame) / 2.0f : _cornerRadius; + return [self _isCapsuleShape] ? CGRectGetHeight(self.trackView.frame) / 2.0f : _cornerRadius; } - (void)_updateCornerRadius { const CGFloat cornerRadius = [self _cornerRadiusValue]; self.trackView.layer.cornerRadius = cornerRadius; - self.thumbView.layer.cornerRadius = (cornerRadius - _thumbInset) + 1.0f; + self.thumbView.layer.cornerRadius = (cornerRadius - _thumbInset); + +#ifdef __IPHONE_13_0 + if (@available(iOS 13.0, *)) { + self.thumbView.layer.cornerCurve = kCACornerCurveContinuous; + self.trackView.layer.cornerCurve = kCACornerCurveContinuous; + } +#endif } // ----------------------------------------------- From fe0a17c7fe1522ba81ecec054c82e4160431d61f Mon Sep 17 00:00:00 2001 From: Tim Oliver Date: Sat, 8 Nov 2025 18:47:34 +0900 Subject: [PATCH 2/3] Added Liquid Glass support --- TOSegmentedControl/TOSegmentedControl.h | 3 ++ TOSegmentedControl/TOSegmentedControl.m | 49 ++++++++++++++++++------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/TOSegmentedControl/TOSegmentedControl.h b/TOSegmentedControl/TOSegmentedControl.h index 501c6a2..0bf7d08 100644 --- a/TOSegmentedControl/TOSegmentedControl.h +++ b/TOSegmentedControl/TOSegmentedControl.h @@ -63,6 +63,9 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl /// Set the background color of the track in the segmented control (Default is light grey) @property (nonatomic, strong, null_resettable) IBInspectable UIColor *backgroundColor; +/// Alternatively, set a background material that will be used instead of a solid color. (eg Liquid Glass) +@property (nonatomic, strong, null_resettable) UIVisualEffect *backgroundEffect; + /// Set the color of the thumb view. (Default is white) @property (nonatomic, strong, null_resettable) IBInspectable UIColor *thumbColor; diff --git a/TOSegmentedControl/TOSegmentedControl.m b/TOSegmentedControl/TOSegmentedControl.m index f77b1a7..ca15786 100644 --- a/TOSegmentedControl/TOSegmentedControl.m +++ b/TOSegmentedControl/TOSegmentedControl.m @@ -65,7 +65,7 @@ @interface TOSegmentedControl () @property (nonatomic, assign) NSInteger focusedIndex; /** The background rounded "track" view */ -@property (nonatomic, strong) UIView *trackView; +@property (nonatomic, strong) UIVisualEffectView *trackView; /** The view that shows which view is highlighted */ @property (nonatomic, strong) UIView *thumbView; @@ -135,7 +135,7 @@ - (instancetype)init { - (void)commonInit { // Create content view - self.trackView = [[UIView alloc] initWithFrame:self.bounds]; + self.trackView = [[UIVisualEffectView alloc] initWithFrame:self.bounds]; self.trackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.trackView.layer.masksToBounds = YES; @@ -146,7 +146,7 @@ - (void)commonInit { // Create thumb view self.thumbView = [[UIView alloc] initWithFrame:CGRectMake(2.0f, 2.0f, 100.0f, 28.0f)]; self.thumbView.layer.shadowColor = [UIColor blackColor].CGColor; - [self.trackView addSubview:self.thumbView]; + [self.trackView.contentView addSubview:self.thumbView]; // Create list for managing each item self.segments = [NSMutableArray array]; @@ -239,7 +239,7 @@ - (void)updateSeparatorViewCount { while (self.separatorViews.count < numberOfSeparators) { UIImageView *separator = [[UIImageView alloc] initWithImage:self.separatorImage]; separator.tintColor = self.separatorColor; - [self.trackView insertSubview:separator atIndex:0]; + [self.trackView.contentView insertSubview:separator atIndex:0]; [self.separatorViews addObject:separator]; } @@ -560,7 +560,7 @@ - (void)layoutItemViews { for (TOSegmentedControlSegment *item in self.segments) { UIView *itemView = item.itemView; [itemView sizeToFit]; - [self.trackView addSubview:item.containerView]; + [self.trackView.contentView addSubview:item.containerView]; // Get the container frame that the item will be aligned with CGRect thumbFrame = [self frameForSegmentAtIndex:i]; @@ -1273,15 +1273,20 @@ - (CGFloat)_cornerRadiusValue { - (void)_updateCornerRadius { const CGFloat cornerRadius = [self _cornerRadiusValue]; - self.trackView.layer.cornerRadius = cornerRadius; - self.thumbView.layer.cornerRadius = (cornerRadius - _thumbInset); + if (@available(iOS 26.0, *)) { + self.trackView.cornerConfiguration = [UICornerConfiguration configurationWithRadius:[UICornerRadius fixedRadius:cornerRadius]]; + self.thumbView.cornerConfiguration = [UICornerConfiguration configurationWithRadius:[UICornerRadius fixedRadius:cornerRadius - _thumbInset]]; + } else { + self.trackView.layer.cornerRadius = cornerRadius; + self.thumbView.layer.cornerRadius = (cornerRadius - _thumbInset); -#ifdef __IPHONE_13_0 - if (@available(iOS 13.0, *)) { - self.thumbView.layer.cornerCurve = kCACornerCurveContinuous; - self.trackView.layer.cornerCurve = kCACornerCurveContinuous; + #ifdef __IPHONE_13_0 + if (@available(iOS 13.0, *)) { + self.thumbView.layer.cornerCurve = kCACornerCurveContinuous; + self.trackView.layer.cornerCurve = kCACornerCurveContinuous; + } + #endif } -#endif } // ----------------------------------------------- @@ -1358,6 +1363,24 @@ - (UIColor *)backgroundColor { return self.trackView.backgroundColor; } +// ----------------------------------------------- + +- (void)setBackgroundEffect:(UIVisualEffect *)effect { + _trackView.backgroundColor = nil; + _trackView.effect = effect; + + // Exit out if we don't need to reset to defaults + if (_trackView.effect != nil) { + return; + } + + // If we nil out the effect, restore the original background color + self.backgroundColor = nil; +} +- (UIVisualEffect *)backgroundEffect { + return self.trackView.effect; +} + // ----------------------------------------------- // Separator Color @@ -1473,7 +1496,7 @@ - (void)setSelectedTextFont:(UIFont *)selectedTextFont { - (void)setThumbInset:(CGFloat)thumbInset { _thumbInset = thumbInset; - self.thumbView.layer.cornerRadius = ([self _cornerRadiusValue] - _thumbInset) + 1.0f; + self.thumbView.layer.cornerRadius = ([self _cornerRadiusValue] - _thumbInset); } // ----------------------------------------------- From cea01c2b9d1013f19ed4ffe143b4b20d23e131a2 Mon Sep 17 00:00:00 2001 From: Tim Oliver Date: Sat, 8 Nov 2025 19:02:27 +0900 Subject: [PATCH 3/3] Reverted Liquid Glass support --- TOSegmentedControl/TOSegmentedControl.h | 3 --- TOSegmentedControl/TOSegmentedControl.m | 28 +++++-------------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/TOSegmentedControl/TOSegmentedControl.h b/TOSegmentedControl/TOSegmentedControl.h index 0bf7d08..501c6a2 100644 --- a/TOSegmentedControl/TOSegmentedControl.h +++ b/TOSegmentedControl/TOSegmentedControl.h @@ -63,9 +63,6 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl /// Set the background color of the track in the segmented control (Default is light grey) @property (nonatomic, strong, null_resettable) IBInspectable UIColor *backgroundColor; -/// Alternatively, set a background material that will be used instead of a solid color. (eg Liquid Glass) -@property (nonatomic, strong, null_resettable) UIVisualEffect *backgroundEffect; - /// Set the color of the thumb view. (Default is white) @property (nonatomic, strong, null_resettable) IBInspectable UIColor *thumbColor; diff --git a/TOSegmentedControl/TOSegmentedControl.m b/TOSegmentedControl/TOSegmentedControl.m index ca15786..55e4ed9 100644 --- a/TOSegmentedControl/TOSegmentedControl.m +++ b/TOSegmentedControl/TOSegmentedControl.m @@ -65,7 +65,7 @@ @interface TOSegmentedControl () @property (nonatomic, assign) NSInteger focusedIndex; /** The background rounded "track" view */ -@property (nonatomic, strong) UIVisualEffectView *trackView; +@property (nonatomic, strong) UIView *trackView; /** The view that shows which view is highlighted */ @property (nonatomic, strong) UIView *thumbView; @@ -135,7 +135,7 @@ - (instancetype)init { - (void)commonInit { // Create content view - self.trackView = [[UIVisualEffectView alloc] initWithFrame:self.bounds]; + self.trackView = [[UIView alloc] initWithFrame:self.bounds]; self.trackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.trackView.layer.masksToBounds = YES; @@ -146,7 +146,7 @@ - (void)commonInit { // Create thumb view self.thumbView = [[UIView alloc] initWithFrame:CGRectMake(2.0f, 2.0f, 100.0f, 28.0f)]; self.thumbView.layer.shadowColor = [UIColor blackColor].CGColor; - [self.trackView.contentView addSubview:self.thumbView]; + [self.trackView addSubview:self.thumbView]; // Create list for managing each item self.segments = [NSMutableArray array]; @@ -239,7 +239,7 @@ - (void)updateSeparatorViewCount { while (self.separatorViews.count < numberOfSeparators) { UIImageView *separator = [[UIImageView alloc] initWithImage:self.separatorImage]; separator.tintColor = self.separatorColor; - [self.trackView.contentView insertSubview:separator atIndex:0]; + [self.trackView insertSubview:separator atIndex:0]; [self.separatorViews addObject:separator]; } @@ -560,7 +560,7 @@ - (void)layoutItemViews { for (TOSegmentedControlSegment *item in self.segments) { UIView *itemView = item.itemView; [itemView sizeToFit]; - [self.trackView.contentView addSubview:item.containerView]; + [self.trackView addSubview:item.containerView]; // Get the container frame that the item will be aligned with CGRect thumbFrame = [self frameForSegmentAtIndex:i]; @@ -1363,24 +1363,6 @@ - (UIColor *)backgroundColor { return self.trackView.backgroundColor; } -// ----------------------------------------------- - -- (void)setBackgroundEffect:(UIVisualEffect *)effect { - _trackView.backgroundColor = nil; - _trackView.effect = effect; - - // Exit out if we don't need to reset to defaults - if (_trackView.effect != nil) { - return; - } - - // If we nil out the effect, restore the original background color - self.backgroundColor = nil; -} -- (UIVisualEffect *)backgroundEffect { - return self.trackView.effect; -} - // ----------------------------------------------- // Separator Color