Obj-C iPhone UISegmentedControl в UITableView - PullRequest
2 голосов
/ 12 марта 2011

В моей таблице 9 разделов (они извлекаются из массива). В 4 разделах у меня будет 1 строка, которая поднимает UIPickerView. В 5 из этих разделов мне понадобятся 5 различных UISegmentedControls с различным количеством опций выбора (2-5 опций). У кого-нибудь есть какие-либо советы по реализации?

Должен ли я создавать отдельные файлы xib для каждого UISegmentedControl? Я чувствую, что есть / должен быть лучший способ сделать это.

Любая помощь будет оценена!

Ответы [ 3 ]

2 голосов
/ 12 марта 2011

У вас есть структура таблицы в 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] 

Вот как я настраивал 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]];
}

и, конечно, вам также нужны сеттер и геттер для указанного ключа:

- (NSNumber *)foo {
    return [NSNumber numberWithInt:someValue];
}

- (void)setFoo:(NSNumber *)n {
    someValue = [n intValue];
}

Вы можете синтезировать их, но я хотел, чтобы в моем классе было значение int вместо NSNumbers, поэтому я сам написал установщик и получатель.


Большим преимуществом этого является то, что он полностью динамичный. Если вы хотите переставить ячейки, просто переместите их в массив (я использую plist, чтобы сделать это еще проще).

Это немного сложно, когда вы используете его в первый раз, но все становится довольно быстро. И вам не нужны пять разных .xibs и пять разных UISegmentedControls в интерфейсе вашего класса.

1 голос
/ 13 марта 2011

В объекте indexPath у вас есть возможность взглянуть на row и section элемента таблицы.В этот момент вы можете просто решить, что отображать, ваше представление, какой-либо текст или другое представление, как значение cell.Помните, что ячейка - это UIView, поэтому вы можете добавлять подпредставления и все такое.Документы Apple для UITableView фактически содержат раздел о том, как создавать статические ячейки с контроллерами в них, а также как переопределить cell объекты с другими представлениями.

Поскольку все статично, вы можете просто проверить наличиеразделы, использующие оператор switch, как этот, в вашей обычной cellForRowAtIndexPath:

- (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;
}
0 голосов
/ 12 марта 2011

Есть несколько способов сделать это легко.

  1. Вы можете установить тег для UISegmentedControl и получить к нему доступ таким образом.
  2. Вы можете программно создать элемент управления для каждого раздела.Это также потребует от вас установки тега, чтобы вы могли получить к нему доступ другими способами.

Это, на мой взгляд, самый простой способ достичь того, что вы хотите сделать.

Оба эти способа потребуют от вас определения элемента управления в заголовке.

.h

@interface MyViewController : UIViewController
{
    UISegmentedControl *myControl;
}
@property (nonatmoic, retain) UISegmentedControl *segment;
@end

.m

#import "MyViewControler.h"
@implementation MyViewController
@synthesize myControl;
. . .
...