方案
我的子类UISegmentedControl
中有一个奇怪的错误。我所做的只是将UISegmentedControl
子类化为删除选择/取消选择的默认指标,并使用自定义CALayer
作为指标。与此同时,我修改了titleTextAttributes
以补充用户界面。
问题
当视图首次出现且默认选择的索引为0时,它看起来像这样:
当我尝试将selectedSegmentIndex
更改为1时,它变为:
它应该是这样的(一旦你改变selectedSegmentIndex
几次就更正了):
titleTextAttributes
这种{not}不变的行为是随机的,但是这种情况在100%的情况下发生的情况是:
我没有在UISegmentedControl
官方文档中找到子类注释。
示例项目HERE。
注意:如果您只使用2个细分,则在选择时,您将永远不会在索引1处看到细分的标题。
答案 0 :(得分:1)
确实这是一种奇怪的行为。
您可以解决此问题,在更改指示图层框架后添加对[self setNeedsLayout]
的显式调用。
//
// RBLSegmentedControl.m
// Rabbler
//
// Created by Utkarsh Singh on 05/11/15.
// Copyright © 2015 Neeraj SIngh. All rights reserved.
//
#import "NPSegmentedControl.h"
@interface NPSegmentedControl ()
@property (nonatomic, retain) CALayer* selectedIndicationLayer;
@end
@implementation NPSegmentedControl
- (instancetype)initWithItems:(NSArray *)items {
if (self = [super initWithItems:items]) {
self.selectedIndicationLayer.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width / items.count, self.frame.size.height);
[self addTarget:self action:@selector(segmentedControlDidChange) forControlEvents:UIControlEventValueChanged];
NSDictionary* selectedAttributes = @{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue-Light" size:15],
NSForegroundColorAttributeName:[UIColor whiteColor]};
NSDictionary* deselectedAttributes = @{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue-Light" size:15],
NSForegroundColorAttributeName:[UIColor redColor]};
NSDictionary* highlightedAttributes = @{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue-Light" size:15],
NSForegroundColorAttributeName:[[UIColor redColor] colorWithAlphaComponent:0.6f]};
[self setTitleTextAttributes:deselectedAttributes forState:UIControlStateNormal];
[self setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected];
[self setTitleTextAttributes:highlightedAttributes forState:UIControlStateHighlighted];
}
return self;
}
- (void) segmentedControlDidChange {
[self animateSegmentSelectionChange];
if (self.delegate && [self.delegate respondsToSelector:@selector(segmentedControlDidChangeSelectedSegment:)]) {
[self.delegate segmentedControlDidChangeSelectedSegment:self.selectedSegmentIndex];
}
}
- (void) animateSegmentSelectionChange {
[UIView animateWithDuration:0.25
delay:0
options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState)
animations:^{
CGRect frame = self.selectedIndicationLayer.frame;
frame.origin.x = self.selectedSegmentIndex * [UIScreen mainScreen].bounds.size.width / self.numberOfSegments;
self.selectedIndicationLayer.frame = frame;
[self setNeedsLayout]; // <--
} completion:nil];
}
- (CALayer *) selectedIndicationLayer {
if (!_selectedIndicationLayer) {
_selectedIndicationLayer = [CALayer layer];
_selectedIndicationLayer.backgroundColor = [[UIColor redColor] CGColor];
_selectedIndicationLayer.cornerRadius = self.frame.size.height /2;
_selectedIndicationLayer.borderColor = [UIColor whiteColor].CGColor;
_selectedIndicationLayer.borderWidth = 1.5f;
[self.layer insertSublayer:_selectedIndicationLayer atIndex:0];
}
return _selectedIndicationLayer;
}
- (void) setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex {
[super setSelectedSegmentIndex:selectedSegmentIndex];
[self animateSegmentSelectionChange];
}
- (void) setIndicatorColor:(UIColor *)indicatorColor {
self.selectedIndicationLayer.backgroundColor = indicatorColor.CGColor;
}
@end
答案 1 :(得分:0)
我将您的selectedIndicationLayer
更改为此问题并解决问题
- (CALayer *) selectedIndicationLayer {
if (!_selectedIndicationLayer) {
_selectedIndicationLayer = [CALayer layer];
_selectedIndicationLayer.backgroundColor = [[UIColor redColor] CGColor];
_selectedIndicationLayer.cornerRadius = self.frame.size.height /2;
_selectedIndicationLayer.borderColor = [UIColor whiteColor].CGColor;
_selectedIndicationLayer.borderWidth = 1.5f;
}
if ([self.layer.sublayers containsObject:_selectedIndicationLayer]) {
[_selectedIndicationLayer removeFromSuperlayer];
}
[self.layer insertSublayer:_selectedIndicationLayer atIndex:0];
return _selectedIndicationLayer;
}
答案 2 :(得分:0)
只需编辑以下方法即可。
- (CALayer *) selectedIndicationLayer {
if (!_selectedIndicationLayer) {
_selectedIndicationLayer = [CALayer layer];
_selectedIndicationLayer.backgroundColor = [[UIColor redColor] CGColor];
_selectedIndicationLayer.cornerRadius = self.frame.size.height /2;
_selectedIndicationLayer.borderColor = [UIColor whiteColor].CGColor;
_selectedIndicationLayer.borderWidth = 1.5f;
}
[self.layer insertSublayer:_selectedIndicationLayer atIndex:0];
return _selectedIndicationLayer;
}