UITableView中的Obj-C iPhone UI分段控件
我的表中有9个部分(它们是从数组中提取的)。在4个部分中,我将有1行拉入UIPickerView。在其中的5个部分中,我需要5个不同的UISegmentedControls,具有不同数量的选择选项(2-5个选项)。有没有人能给我一些关于实现这个的建议 我应该为每个UISegmentedControl构建单独的xib文件吗?我觉得会/应该有更好的方法来做到这一点UITableView中的Obj-C iPhone UI分段控件,iphone,objective-c,uitableview,uisegmentedcontrol,Iphone,Objective C,Uitableview,Uisegmentedcontrol,我的表中有9个部分(它们是从数组中提取的)。在4个部分中,我将有1行拉入UIPickerView。在其中的5个部分中,我需要5个不同的UISegmentedControls,具有不同数量的选择选项(2-5个选项)。有没有人能给我一些关于实现这个的建议 我应该为每个UISegmentedControl构建单独的xib文件吗?我觉得会/应该有更好的方法来做到这一点 任何帮助都将不胜感激 有几种方法可以轻松做到这一点 您可以设置UISegmentedControl的标记,然后像这样访问它 可以通过编程
任何帮助都将不胜感激 有几种方法可以轻松做到这一点
UISegmentedControl
的标记,然后像这样访问它您的表结构位于NSArray中,因此我建议您为应该具有分段控件的每一行创建一个NSDictionary,并将其添加到表结构NSArray中 词典中需要三个对象。一个标题,一个包含段名称的NSArray,以及一个用于设置和获取所选索引的键 我在一些应用程序中对设置viewcontroller做了类似的操作。这是NSDictionary的外观:
[NSDictionary dictionaryWithObjectsAndKeys:
@"Value of Foo", kSettingsLabel, // for the textLabel
[UISegmentedControl class], kSettingsView, // which UIControl
@"foo", kSettingsKey, // the key for setValue:forKey: and valueForKey:
[NSArray arrayWithObjects: @"Green", @"Round", @"Auto",nil], kSettingsValue, // the titles of the segments
nil]
以下是我在tableview中设置UISegmentedControls的方法:
NSDictionary *dictionary = [[self.dataSourceArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
// omitted: check in the dictionary which cell we need... (I wrote it that it can use almost all UIControls)
// omitted: dequeue a cell with a UISegmentedControl ...
// configure cell:
NSArray *segmentTitles = [dictionary objectForKey:kSettingsValue];
UISegmentedControl *segment = (UISegmentedControl *)[cell viewWithTag:kTagSegment];
[segment removeAllSegments];
for (NSString *segmentName in segmentTitles) {
// if index is higher than number of indexes title is inserted at last available index.
// so first object in array is placed at first position in segmentcontrol
[segment insertSegmentWithTitle:segmentName atIndex:1000 animated:NO];
}
[segment setSelectedSegmentIndex:[[self valueForKey:[dictionary valueForKey:kSettingsKey]] intValue]];
//omitted: setup cell title ... and return cell
UISegmentedControl连接到如下所示的值更改操作:
NSIndexPath *indexPath = [self.settingsTable indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
if (indexPath == nil)
return;
NSDictionary *dictionary = [[self.dataSourceArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
if ([sender isKindOfClass:[UISegmentedControl class]]) {
[self setValue:[NSNumber numberWithInt:((UISegmentedControl *)sender).selectedSegmentIndex] forKey:[dictionary valueForKey:kSettingsKey]];
}
当然,您还需要指定键的setter和getter:
- (NSNumber *)foo {
return [NSNumber numberWithInt:someValue];
}
- (void)setFoo:(NSNumber *)n {
someValue = [n intValue];
}
你可以合成它们,但我想在我的类中有int值而不是nsnumber,所以我自己编写了setter和getter
这样做的最大优点是它是完全动态的。如果您想重新排列单元格,只需在数组中移动它们(我使用plist使之更容易)
当你第一次使用它的时候,它有点复杂,但是它很快就会变得清晰。在类接口中不需要五个不同的.xib和五个不同的UISegmentedControl 在
indexPath
对象中,您可以查看tableview项的行和部分。在这一点上,您就可以决定显示什么,您的视图,一些文本或另一个视图,无论是单元格的值是什么。请记住,单元格是UIView,因此可以添加子视图以及所有这些。UtableView的Apple文档中实际上有一节介绍了如何创建包含控制器的静态单元格,以及如何用其他视图覆盖cell
对象
由于所有内容都是静态的,因此您可以在常规的cellforrowatinexpath
中使用类似于下面的switch语句来检查这些部分:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"aCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
reuseIdentifier:MyIdentifier] autorelease]; }
switch ([indexPath section]) {
case 0:{
cell.textLabel.text = @"The first section's cell";
break;
}
case 1:{
switch ([indexPath row]) {
case 0:{
//The first row of the second section
break;
}
case 1:{
//The second row of the second section
break;
}
case 2:{
//The third row of the second section
break;
}
}
break;
}
case 2:{
//the third section
break;
}
case 3:{
//the fourth section
cell.textLabel.text = @"Notes";
cell.detailTextLabel.text = currentClient.Notes;
break;
}
default:
break;
}
return cell;
}
这样,我就不用IB了,对吧?这看起来比我想要的稍微复杂一些,因为这些行永远不需要是动态的。我很感激发布代码的努力(这实际上可能会在应用程序中的不同视图中使用),但是对于静态表,您可以推荐一种不同的方法吗?我使用了一个.xib,它有10个UITableViewCells用于我需要的所有不同单元格。老实说,对于静态表,我会用几乎相同的方法来做。使用单元格布局创建.xib,并在代码中创建段标题。当这是静态的时,不需要字典或键值访问。带有硬编码值的if(row==1)/*设置单元格*/
就足够了。太好了!在我的例子中,我会使用'if(section==1)/*setup cell*/,但想法保持不变。那么,接下来做一些事情,比如用代码而不是IB设置段标题有什么好处?如果我在处理IB,我是不是可以通过在IB中设置它们来节省一些代码,或者我在这里遗漏了什么?当然,您可以在Interface Builder中创建每一行。这样做没有问题。我通常不这样做,因为当我想让片段变宽一点时,我必须在5个细胞上做。我至少改变了10次界面元素的位置。我的所有应用程序都至少用两种语言发布,所以代码方式还有另一个优势。但是使用interface builder并没有错。做最适合你的事。如果你喜欢在IB中做,那就做吧。太好了!非常感谢你的帮助!!你能详细说明一下这些方法吗?我已经在标题中定义了所需的所有内容,并在.m中合成了它们,但我不知道如何巧妙地确定哪个UISegmentedControl将放在哪个部分。
- (NSNumber *)foo {
return [NSNumber numberWithInt:someValue];
}
- (void)setFoo:(NSNumber *)n {
someValue = [n intValue];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"aCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
reuseIdentifier:MyIdentifier] autorelease]; }
switch ([indexPath section]) {
case 0:{
cell.textLabel.text = @"The first section's cell";
break;
}
case 1:{
switch ([indexPath row]) {
case 0:{
//The first row of the second section
break;
}
case 1:{
//The second row of the second section
break;
}
case 2:{
//The third row of the second section
break;
}
}
break;
}
case 2:{
//the third section
break;
}
case 3:{
//the fourth section
cell.textLabel.text = @"Notes";
cell.detailTextLabel.text = currentClient.Notes;
break;
}
default:
break;
}
return cell;
}