UISegmentedControl段令混淆

时间:2014-05-24 06:09:50

标签: ios objective-c ios7 uisegmentedcontrol

我试图扩展UISegmentedControl的功能,并且遇到了处理各个细分的问题。这个问题似乎比较通用,所以我从一个在线示例中借用了一些代码:http://www.framewreck.net/2010/07/custom-tintcolor-for-each-segment-of.html

为便于参考:

UISegmentedControlExtension.h

@interface UISegmentedControl(CustomTintExtension)
-(void)setTag:(NSInteger)tag forSegmentAtIndex:(NSUInteger)segment;
-(void)setTintColor:(UIColor*)color forTag:(NSInteger)aTag;
-(void)setTextColor:(UIColor*)color forTag:(NSInteger)aTag;
-(void)setShadowColor:(UIColor*)color forTag:(NSInteger)aTag;
@end

UISegmentedControlExtension.m

#import "UISegmentedControlExtension.h"

@implementation UISegmentedControl(CustomTintExtension)

-(void)setTag:(NSInteger)tag forSegmentAtIndex:(NSUInteger)segment {
[[[self subviews] objectAtIndex:segment] setTag:tag];
}

-(void)setTintColor:(UIColor*)color forTag:(NSInteger)aTag {
// must operate by tags.  Subview index is unreliable
UIView *segment = [self viewWithTag:aTag];
SEL tint = @selector(setTintColor:);

// UISegment is an undocumented class, so tread carefully
// if the segment exists and if it responds to the setTintColor message
if (segment && ([segment respondsToSelector:tint])) {
 [segment performSelector:tint withObject:color];
}
}

-(void)setTextColor:(UIColor*)color forTag:(NSInteger)aTag {
UIView *segment = [self viewWithTag:aTag];
for (UIView *view in segment.subviews) {
 SEL text = @selector(setTextColor:);

 // if the sub view exists and if it responds to the setTextColor message
 if (view && ([view respondsToSelector:text])) {
  [view performSelector:text withObject:color];
 }
}
}

-(void)setShadowColor:(UIColor*)color forTag:(NSInteger)aTag {

// you probably know the drill by now
// you could also combine setShadowColor and setTextColor
UIView *segment = [self viewWithTag:aTag];
for (UIView *view in segment.subviews) {
 SEL shadowColor = @selector(setShadowColor:);
 if (view && ([view respondsToSelector:shadowColor])) {
  [view performSelector:shadowColor withObject:color];
 }
}
}

@end

上面的例子声称"在某个时候,段索引会发生变化" - 我不相信这种情况,但是索引肯定会发生一些奇怪的事情:

[_segmentedControl titleForSegmentAtIndex:i]

然后使用示例代码:

[_segmentedControl setTintColor:[UIColor blueColor] forTag:Blue];

如果我使用段的标题检查并映射每个段的索引:

typedef NS_ENUM(int, colorvalues) {
    Blue, Brown, Green, Red, White, Yellow
};
if ([@"Blue" isEqual: title]) {
    NSLog(@"Setting Blue(%d) tag on segment: %d", Blue, i);
    [_segmentedControl setTag:Blue forSegmentAtIndex:i];
} else if ([@"Brown" isEqual: title]) {
    NSLog(@"Setting Brown tag on segment: %d", i);
    [_segmentedControl setTag:Brown forSegmentAtIndex:i];
} else if ([@"Green" isEqual: title]) {
    NSLog(@"Setting Green tag on segment: %d", i);
    [_segmentedControl setTag:Green forSegmentAtIndex:i];
} else if ([@"Red" isEqual: title]) {
    NSLog(@"Setting Red tag on segment: %d", i);
    [_segmentedControl setTag:Red forSegmentAtIndex:i];
} else if ([@"White" isEqual: title]) {
    NSLog(@"Setting White tag on segment: %d", i);
    [_segmentedControl setTag:White forSegmentAtIndex:i];
} else if ([@"Yellow" isEqual: title]) {
    NSLog(@"Setting Yellow tag on segment: %d", i);
    [_segmentedControl setTag:Yellow forSegmentAtIndex:i];
}

然后使用上面的示例代码设置Tint:

[_segmentedControl setTintColor:[UIColor blueColor] forTag:Blue];
[_segmentedControl setTintColor:[UIColor brownColor] forTag:Brown];
[_segmentedControl setTintColor:[UIColor greenColor] forTag:Green];
[_segmentedControl setTintColor:[UIColor redColor] forTag:Red];
[_segmentedControl setTintColor:[UIColor whiteColor] forTag:White];
[_segmentedControl setTintColor:[UIColor yellowColor] forTag:Yellow];

我最终得到了:

demented SegmentedControl

如果我以编程方式创建UISegmentedControl,我可以通过在将选定的段添加到子视图之前设置所选的段来影响索引的偏移。将选定的段设置为0时,正确排列。但是,通过界面构建​​器,即使通过GUI选择不同的选定段,事情也会一直被破坏。我假设是因为在选择片段之前将控件添加到子视图中。

任何想法导致这种奇怪的行为?

1 个答案:

答案 0 :(得分:1)

[[[self subviews] objectAtIndex:segment] setTag:tag];

此行有问题。以相反的顺序设置段。例如

#define kTagSecond 222
#define kTagFirst 111
[self.segment setTag:kTagFirst forSegmentAtIndex:1];
[self.segment setTag:kTagSecond forSegmentAtIndex:0];

其中kTagFirst是第一个段,kTagSecond是第二个段