Как добавить подвид в ListView?

Я разрабатываю свое первое приложение MAC, я скачал один пример PxListView

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

но теперь я хочу развиваться, как после того, как ячейка ведьмы открылась в этой ячейке, я хочу добавить в нее дополнительное содержимое (контроллер), так как это будет возможно, используя данный пример? пожалуйста, помогите мне дать некоторые предложения, как это будет сделано.
для примера, как прежде, нажмите на кнопку введите описание изображения  здесь

после цыпленка на кнопке я хочу развиваться как

введите здесь описание изображения


person Bittu    schedule 25.12.2012    source источник
comment
Ваш второй абзац не ясен. У вас есть кнопка, которая увеличивает размер одного из представлений списка? Это уже работает? Не могли бы вы опубликовать соответствующие части вашего кода?   -  person paulmelnikow    schedule 27.12.2012


Ответы (1)


Вы пишете

я должен добавить одну кнопку и фоновое изображение в ячейку xib и связать их с контроллером

Похоже, вы создали подкласс PXListViewCell — для удобства назовем ваш подкласс TemplateListViewCell — и добавили xib, из которого будут загружаться экземпляры TemplateListViewCell.

+[PXListViewCell cellLoadedFromNibNamed:bundle:reusableIdentifier:]

Кроме того, в TemplateListViewCell.xib есть [по крайней мере одна] кнопка.

Вы пишете

при нажатии кнопки я установил, что высота этой ячейки намного больше, чем другая. это сделано, и работает нормально

Похоже, эта кнопка имеет в качестве действия метод TemplateListViewCell, такой как

- (IBAction)toggleDetail:(id)sender
{
    //Code to grow or shrink the height of [self frame].  
    //...
}

В моем подходе к реализации -toggleDetail потребовались две модификации файлов PXListView:

1. Добавление метода протокола

- (void)listView:(PXListView *)aListView setHeight:(CGFloat)height ofRow:(NSUInteger)row;

к протоколу PXListViewDelegate.

2. Добавление свойства

@property (nonatomic, assign) BOOL expanded;

to PXListViewCell.

Моя реализация -toggleDetail выглядит примерно так:

- (IBAction)toggleDetail:(id)sender
{
    BOOL wasExpanded = [self expanded];

    NSRect oldFrame = [self frame];
    CGFloat oldHeight = oldFrame.size.height;
    CGFloat newHeight = oldHeight;

    CGFloat heightIncrement = 0.0f;
    if (wasExpanded) {
        heightIncrement = -80.0f; //use whatever value is appropriate
    } else {
        heightIncrement = 80.0f;  //use whatever value is appropriate
    }
    newHeight += heightIncrement;

    [[[self listView] delegate] listView:[self listView] setHeight:newHeight ofRow:[self row]];
    [[self listView] reloadData];

    BOOL isExpanded = !wasExpanded;
    [self setExpanded:isExpanded];
}

Может показаться, что лучше использовать [[self listView] reloadRowAtIndex:[self row]]; вместо [[self listView] reloadData], но, к сожалению, это не работает: если пользователь скрывает детали — сжимает ячейку по вертикали — новые ячейки, которые должны появиться на экране, не отображаются.

Вы пишете

это сделано, и работает нормально.

Похоже, вы смогли успешно реализовать метод, аналогичный -[TemplateListViewCell toggleDetail:].

Вы пишете

но теперь я хочу развиваться, как после того, как ячейка ведьмы открылась в этой ячейке, я хочу добавить в нее дополнительное содержимое (контроллер), так как это будет возможно, используя данный пример? Пожалуйста, помогите мне дать некоторые предложения, как это будет сделано.

Похоже, вы хотите, чтобы экземпляры TemplateListViewCell содержали дополнительные представления, если они развернуты.

Может показаться заманчивым поместить этот код в -[TemplateListViewCell toggleDetail], но это не сработает, как мы могли бы надеяться. Проблема в том, что нам нужно обрабатывать случаи, когда расширенные ячейки были прокручены из поля зрения и возвращены в поле зрения.

Чтобы сделать это правильно, нам нужно иметь понятие расширенного, которое сохраняется за пределами использования экземпляра подкласса PXListViewCell: нам нужно либо отслеживать расширение в самом PXListView, либо в его делегате.

Кажется, что лучший, но менее целесообразный дизайн состоит в том, чтобы отслеживать эту информацию в самом PXListView. Однако ради ответа на этот вопрос я покажу, как отслеживать расширение ячейки в делегате. Для этого я расширяю протокол PXListViewDelegate и вношу другие изменения в файлы PXListView:

1. Добавление методов

- (void)listView:(PXListView *)aListView setExpanded:(BOOL)expanded atRow:(NSUInteger)row;
- (BOOL)listView:(PXListView *)aListView expandedAtRow:(NSUInteger)row;

to PXListViewDelegate.

2. Добавление метода

- (void)setCell:(PXListViewCell *)cell expandedAtRow:(NSUInteger)row
{
    if ([[self delegate] respondsToSelector:@selector(listView:expandedAtRow:)]) {
        [cell setExpanded:[[self delegate] listView:self expandedAtRow:row]];
    }
}

to PXListView.

3. Звонок -[PXListView setCell:expandedAtRow:] из -[PXListView layoutCells]

- (void)layoutCells
{   
    //Set the frames of the cells
    for(id cell in _visibleCells)
    {
        NSInteger row = [cell row];
        [cell setFrame:[self rectOfRow:row]];


        [self setCell:cell expandedAtRow:row];


        [cell layoutSubviews];
    }

    NSRect bounds = [self bounds];
    CGFloat documentHeight = _totalHeight>NSHeight(bounds)?_totalHeight:(NSHeight(bounds) -2);

    //Set the new height of the document view
    [[self documentView] setFrame:NSMakeRect(0.0f, 0.0f, NSWidth([self contentViewRect]), documentHeight)];
}

и от -[PXListView layoutCell:atRow:]:

- (void)layoutCell:(PXListViewCell*)cell atRow:(NSUInteger)row
{
    [[self documentView] addSubview:cell];
    [cell setFrame:[self rectOfRow:row]];

    [cell setListView:self];
    [cell setRow:row];
    [cell setHidden:NO];

    [self setCell:cell expandedAtRow:row];
}

4. Настройка _expanded на NO в -[PXListViewCell prepareForReuse]:

- (void)prepareForReuse
{
    _dropHighlight = PXListViewDropNowhere;
    _expanded = NO;
}

Примечание. В примере PXListViewCell подкласса MyListViewCell , распространяемый с PXListView, реализация -[MyListViewCell prepareForReuse] не вызывает [super prepareForReuse]. Убедитесь, что этот вызов сделан в [TemplateListViewCell prepareForReuse]:

- (void)prepareForReuse
{
    //...
    [super prepareForReuse];
}

Необходимо внести одно изменение в -[TemplateListViewCell toggleDetail:]. Линия

[self setExpanded:isExpanded];

необходимо заменить на

[[[self listView] delegate] listView:[self listView] setExpanded:isExpanded atRow:[self row]];

После того, как вы настроили свой делегат PXListView для правильной обработки новых методов делегата, вы готовы переопределить [PXListViewCell setExpanded:] в своем подклассе TemplateListViewCell:

- (void)setExpanded:(BOOL)expanded
{
    if (expanded) {
        //add detail subviews
    } else {
        //remove detail subviews
    }
    [super setExpanded:expanded];
}

Замените //add detail subviews своим собственным кодом, который программно добавляет нужные подпредставления сведений, и замените //remove detail subviews кодом для удаления нужных подпредставлений сведений, предварительно проверив их наличие.

Вы пишете

я хочу добавить к нему дополнительный контент (контроллер)

Похоже, вы хотите добавить в свой TemplateListViewCell контроллеры представления, а не представления. Для этого используйте NSBox и установите contentView поля на view вашего контроллера представления. (Подробности см. в этом ответе.)

Если вы планируете просто отображать представление одного контроллера представления в NSBox на расширенном TemplateListViewCell, вы можете просто (1) добавить свойство в TemplateListViewCell, ссылающееся на ваш контроллер представления, и (2) добавить NSBox в TemplateListViewCell xib и установить его contentView в соответствующее представление контроллера представления на [cell setExpanded:YES] и установите для его contentView значение nil на [cell setExpanded:NO].

person Nate Chandler    schedule 28.12.2012