Question

I am developing my first MAC application, i downloaded one Example of PxListView

and i have to added one button and background image on cell xib and bind them with controller and, when on button click i was set height of that cell is much bigger then other. that is done, and work fine.

but now i want to develop like after is witch cell has open in that cell i want to add some extra contain (Controller) on it, so how it will possible using given example? pls help me to give some suggest how it will be done.
for Ex like before click on button enter image description here

after chick on button i want to develop like

enter image description here

Was it helpful?

Solution

You write

i have to added one button and background image on cell xib and bind them with controller

It sounds like you've subclassed PXListViewCell--for convenience, let's call your subclass TemplateListViewCell--and added a xib from which instances of TemplateListViewCell will be loaded in

+[PXListViewCell cellLoadedFromNibNamed:bundle:reusableIdentifier:]

In addition, there is a[t least one] button in TemplateListViewCell.xib.

You write

when on button click i was set height of that cell is much bigger then other. that is done, and work fine

It sounds like this button has as its action a method on TemplateListViewCell such as

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

In my approach to implementing -toggleDetail, two modifications to the PXListView files were necessary:

1. Adding a protocol method

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

to the PXListViewDelegate protocol.

2. Adding a property

@property (nonatomic, assign) BOOL expanded;

to PXListViewCell.

My implementation of -toggleDetail looks something like this:

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

It might seem better to use [[self listView] reloadRowAtIndex:[self row]]; in place of [[self listView] reloadData], but unfortunately, this doesn't work: if the user hides the detail--shrinks the cell vertically--new cells which should appear on the screen do not.

You write

that is done, and work fine.

It sounds like you were able to implement successfully a method analogous to -[TemplateListViewCell toggleDetail:].

You write

but now i want to develop like after is witch cell has open in that cell i want to add some extra contain (Controller) on it, so how it will possible using given example? pls help me to give some suggest how it will be done.

It sounds like you want instances of TemplateListViewCell to contain extra views if they are expanded.

It might seem tempting to put this code into -[TemplateListViewCell toggleDetail], but this will not work out as we might hope. The trouble is, we need to handle cases where expanded cells have been scrolled out of view and scrolled back into view.

To get this right, we need to have a notion of expanded which persists beyond the usage of a PXListViewCell subclass instance: we either need to keep track of expansion in the PXListView itself or in its delegate.

The better--but less expedient--design seems to be to keep track of this information in the PXListView itself. For the sake of this question, however, I'll demonstrate how to keep track of cell expansion in the delegate. To do this, I'm expanding the PXListViewDelegate protocol and making other changes to the PXListView files:

1. Adding the methods

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

to PXListViewDelegate.

2. Adding the method

- (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. Calling -[PXListView setCell:expandedAtRow:] from -[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)];
}

and from -[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. Setting _expanded to NO in -[PXListViewCell prepareForReuse]:

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

Note: In the sample PXListViewCell subclass, MyListViewCell, distributed with PXListView, the implementation of -[MyListViewCell prepareForReuse] fails to call [super prepareForReuse]. Make sure that this call is made in [TemplateListViewCell prepareForReuse]:

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

One change needs to be made to -[TemplateListViewCell toggleDetail:]. The line

[self setExpanded:isExpanded];

needs to be replaced by

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

Once you've set up your PXListView's delegate to properly handle the new delegate methods, you're ready to override [PXListViewCell setExpanded:] in your subclass TemplateListViewCell:

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

Replace //add detail subviews with your own code which programmatically adds the detail subviews that you want and replace //remove detail subviews with code to remove the detail subviews that you want, checking to see that they are present first.

You write

i want to add some extra contain (Controller) on it

It sounds like you want to add view controllers rather than views to your TemplateListViewCell. To do this, use an NSBox and set the box's contentView to your view controller's view. (For details on this, see this answer.)

If you plan on just showing a single view controller's view in an NSBox on the expanded TemplateListViewCell, you can just (1) add a property to TemplateListViewCell referencing your view controller and (2) add an NSBox to TemplateListViewCell xib and set its contentView to the appropriate view controller's view on [cell setExpanded:YES] and set its contentView to nil on [cell setExpanded:NO].

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top