如何在ListView中添加子视图?

时间:2012-12-25 13:42:01

标签: macos cocoa nscollectionview

我正在开发我的第一个MAC应用程序,我下载了一个PxListView

的示例

我必须在单元格xib上添加一个按钮和背景图像,并将它们与控制器绑定 并且,当按下按钮时,我被设置为该单元格的高度比其他单元格大得多。这样做了, 工作正常。

但是现在我想开发就像之后是女巫细胞在那个细胞中打开我想在它上面添加一些额外的包含(Controller),那么如何使用给定的例子? 请帮我提一下如何完成。
对于Ex之前点击按钮 enter image description here

按下按钮后,我想像

那样发展

enter image description here

1 个答案:

答案 0 :(得分:2)

你写

  

我必须在单元格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;

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:]的方法。

你写

  

但是现在我想开发就像之后是女巫细胞在那个细胞中打开我想在它上面添加一些额外的包含(Controller),那么如何使用给定的例子?请帮我提一下如何做。

听起来您希望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;

PXListViewDelegate

2.添加方法

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

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;
}

注意:在与PXListView分发的the sample PXListViewCell subclass, MyListViewCell,中,-[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替换为代码,以删除所需的详细子视图,并检查它们是否存在。< / p>

你写

  

我想在其上添加一些额外的包含(Controller)

听起来您想要添加视图控制器而不是视图TemplateListViewCell。为此,请使用NSBox并将框contentView设置为视图控制器的view。 (有关详细信息,请参阅this answer。)

如果您打算在展开的NSBox上的TemplateListViewCell中展示单个视图控制器的视图,您只需(1)向引用您的视图控制器的TemplateListViewCell添加属性即可(2)将NSBox添加到TemplateListViewCell xib,并将其contentView设置为[cell setExpanded:YES]上相应的视图控制器视图,并将其内容视图设置为nil [cell setExpanded:NO] 1}}。