一个继承自UIView的segmentedControl简单实现。代码地址
- 为了方便地使用xib创建,内中的segment都是UIButton实例
- 内部使用tag标识所有的button
- 原本是自用所以限制和错误检查都很少
- 还不能使用字符串创建,每个segment都要单独做图片
初始化
1 - (void) initWithItems:(NSArray *)items;
直接调用的setItems:方法。
1 - (void) setItems:(NSArray *)items;
还只能使用UIImage和UIButton的数组创建,使用其他类的实例会报出错误;会根据image或者button的大小自动从左到右排列。
1 - (void) setSelectedItems:(NSArray *)items;
为了方便,这个方法可以设置所有segment选中状态的图片。
1 - (void) awakeFromNib;
从nib创建。可以是任何样样式,但是需要满足4个条件
1. 设置highlighted和disabled状态的图片
2. 指定tag
3. 绑定TouchDown到segmentPressed:
4. 没有其他子视图
使用
1 - (void) addTarget:(id)target action:(SEL)action 2 forControlEvents:(UIControlEvents)controlEvents;
使用跟UISegmentedControl的方法一样,只是UIControlEventValueChanged之外的事件无效。
1 @property (nonatomic, readonly) NSInteger numberOfSegments; 2 @property (nonatomic, assign) NSInteger selectedSegmentIndex;
跟UISegmentedControl不同的是代码中设置selectedSegmentIndex也会触发添加的action。
效果实现
为了使用起来跟UISegmentedControl效果尽可能相同,主要问题在触发的UIControlEvent和外观的变化上。
1 - (void) setSelectedSegmentIndex:(NSInteger)index { 2 selectedSegmentIndex = index; 3 4 for (int i = 0; i < self.items.count; ++i) { 5 UIButton *v = (UIButton *)[self viewWithTag:i + BS_SEG_BASE_TAG]; 6 v.enabled = (index != i); 7 } 8 if (target_ != nil && action_ != nil) { 9 [target_ performSelector:action_ withObject:self]; 10 } 11 }
触发事件
segmentedControl本身绑定的action的执行通过
1 [target_ performSelector:action_ withObject:self]
消息完成。
众button绑定的event是UIControlEventTouchDown;为了实现代码中选择selectedSegmentIndex也能触发绑定的action,所有的工作都在setSelectedSegmentIndex:方法中完成,而segmentPressed:方法中只是调用setSelectedSegmentIndex:。
视觉效果
说是selected状态图片,其实是highlighted和disabled状态的图片。
1 [button setImage:selectedImage forState:UIControlStateHighlighted]; 2 [button setImage:selectedImage forState:UIControlStateDisabled];
这是因为segment要在点击的时候触发事件,改变图片,并且选中的segment不能再次点击。
点击时button状态变为highlighted,并且在setSelectedSegmentIndex:方法中将button设为disabled状态,效果刚刚好。
吐嘈一下,写字比写代码累多了。