Reputation: 48450
Is it possible to have a UISegmentedControl span two rows on the iPhone? I've seen this done in a few apps, but not finding what I need in the documentation. Perhaps it's a custom UIButton designed to look like UISegmentedControl.
Upvotes: 2
Views: 1033
Reputation: 206
I was looking for this as well.
I even wanted the second row to look like a part of the first, more like a grid. Could only find to use a second UISegmentedControl, and combined it with another trick to take care of the unnecessary rounded edges.
In my implementation I inherit from UIControl (inherits from UIView), Added 2 UISegmentControls, 2 UIViews to clip the edges and make them look as one.
Further I make some adjustments to set the textfields visually back in the centre.
Easily expanded horizontally, and with minor effort a third,... row could be added too.
The header:
// YHSegmentedGridControl.h
#import <UIKit/UIKit.h>
@interface YHSegmentedGridControl : UIControl{
UISegmentedControl *a,*b;
UIView *va,*vb;
}
- (void)setSelectedSegmentIndex:(NSInteger)index;
- (NSInteger)selectedSegmentIndex;
@end
In the .m file:
// YHSegmentedGridControl.m
// UITestSegment2D
// Created by Yh on 22/04/13.
#import "YHSegmentedGridControl.h"
@implementation YHSegmentedGridControl
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self initWithDefaults];
}
return self;
}
The actual work:
-(void) initWithDefaults{
a = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects: @"1", @"2", nil]];
b = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects: @"3", @"4", nil]];
float e = 75;
int d = (int)e/7;
[a setFrame:CGRectMake(0, 0, 2*e, e+2*d)];
[b setFrame:CGRectMake(0, -2*d, 2*e, e+2*d)];
[a setContentOffset:CGSizeMake(0, -d) forSegmentAtIndex:0];
[a setContentOffset:CGSizeMake(0, -d) forSegmentAtIndex:1];
[b setContentOffset:CGSizeMake(0, +d) forSegmentAtIndex:0];
[b setContentOffset:CGSizeMake(0, +d) forSegmentAtIndex:1];
[a addTarget:self
action:@selector(pickOne:)
forControlEvents:UIControlEventValueChanged];
[b addTarget:self
action:@selector(pickOne:)
forControlEvents:UIControlEventValueChanged];
va = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2*e, e)];
vb = [[UIView alloc] initWithFrame:CGRectMake(0, e, 2*e, e)];
[va setClipsToBounds:YES];
[vb setClipsToBounds:YES];
[self setFrame:CGRectMake(0,0,2*e,2*e)];
[va addSubview:a];
[vb addSubview:b];
[self addSubview:va];
[self addSubview:vb];
}
- (void)setSelectedSegmentIndex:(NSInteger)index{
if(index == UISegmentedControlNoSegment){
[a setSelectedSegmentIndex:UISegmentedControlNoSegment];
[b setSelectedSegmentIndex:UISegmentedControlNoSegment];
} else if(index < a.numberOfSegments){
[a setSelectedSegmentIndex:index];
[b setSelectedSegmentIndex:UISegmentedControlNoSegment];
} else if(index < ( a.numberOfSegments + b.numberOfSegments )){
[b setSelectedSegmentIndex:(index - a.numberOfSegments)];
[a setSelectedSegmentIndex:UISegmentedControlNoSegment];
}else
NSLog(@"No such segment: index to high");
}
- (NSInteger)selectedSegmentIndex{
if(a.selectedSegmentIndex != UISegmentedControlNoSegment)
return a.selectedSegmentIndex;
else if(b.selectedSegmentIndex != UISegmentedControlNoSegment)
return b.selectedSegmentIndex + a.numberOfSegments;
else
return UISegmentedControlNoSegment;
return 0;
}
- (void)pickOne:(id)sender{
if(sender == a)
[b setSelectedSegmentIndex:UISegmentedControlNoSegment];
if(sender == b)
[a setSelectedSegmentIndex:UISegmentedControlNoSegment];
//notify
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
@end
Upvotes: 1
Reputation: 2473
It's not possible using standard UISegmentedControl
- you'll have to draw it on your own.
Upvotes: 0