如何为iPhone SDK应用程序实现手风琴视图?

如何为iPhone SDK应用程序实现手风琴视图?,iphone,objective-c,iphone-sdk-3.0,uiview,Iphone,Objective C,Iphone Sdk 3.0,Uiview,有没有人见过iPhone的“手风琴”(可能被称为“动画轮廓”)视图的实现?我找到了一个Cocoa的范例项目,但在尝试一个港口之前,我希望有人已经发明了轮子 要清楚的是,在UIVIEW中,考虑一个区段堆栈,每个区段包含一个页眉,然后包含一些内容。当用户触摸标题(或通过某些消息/事件)时,如果该部分已经打开=>关闭它;如果该节已关闭=>打开它并关闭任何其他打开的节。jQuery中的一个示例如下所示: 在我的例子中,我希望能够在每个部分中放置任何UIView内容 我只想看看一些真正的应用程序谁实现了

有没有人见过iPhone的“手风琴”(可能被称为“动画轮廓”)视图的实现?我找到了一个Cocoa的范例项目,但在尝试一个港口之前,我希望有人已经发明了轮子

要清楚的是,在UIVIEW中,考虑一个区段堆栈,每个区段包含一个页眉,然后包含一些内容。当用户触摸标题(或通过某些消息/事件)时,如果该部分已经打开=>关闭它;如果该节已关闭=>打开它并关闭任何其他打开的节。jQuery中的一个示例如下所示:

在我的例子中,我希望能够在每个部分中放置任何UIView内容


我只想看看一些真正的应用程序谁实现了这一点-只是想知道这是可能的

我会使用UITableView,让每个单元格的高度取决于它是否“打开”,然后从那里开始。调整行的大小很容易,您可以将组合单元格的总高度设置为UITableView中的可用高度,使其看起来像一个手风琴,而不仅仅是一个表格

这是一个应该可以工作的快速破解,但在UITableViewController子类的.h文件中:

bool sectionopen[4]; ///or some other way of storing the sections expanded/closed state
在.m文件中输入如下内容:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 4;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  {
    if (sectionopen[indexPath.row]) {
        return 240;///it's open
    } else {
        return 45;///it's closed
    }

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *mycell = [[[UITableViewCell alloc] init] autorelease];
    mycell.textLabel.text= @"Section Name";
    return mycell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ///turn them all off
    sectionopen[0]=NO;
    sectionopen[1]=NO;
    sectionopen[2]=NO;
    sectionopen[3]=NO;

    ///open this one
    sectionopen[indexPath.row]=YES;

    ///animate the opening and expand the row
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}
这将基本上采取4行,并将他们变成可折叠的部分,其中选择一行将扩大到240像素,并将所有其他行折叠到40。你可以改变所有这些数字,计算出各个部分,然后用它做任何你想做的事情


我已经试过了,效果不错。然后,您可以将其他内容添加到您的单元格创建代码中,以将任何您想要的内容添加到一个部分(如果您愿意,可能包括一个滚动的UITextView)。

我刚刚偶然发现了这一点,并发现mjdth的解决方案非常直接且有用。但是,您可能希望使用

[self.tableView reloadRowsAtIndexPaths: paths withRowAnimation:UITableViewRowAnimationBottom];

由于重载行提供了更平滑的过渡,因此不再使用建议的
reloadSections
方法。

以下是我目前正在使用的
collasingTableViewDelegate
类。这仅适用于静态表内容

您向此类提供了
collasingTableCellDelegate
实现,此类必须知道如何计算每行的折叠和展开大小,以及如何为每行创建
UIView
。视图在折叠或展开时保持不变,因此每行视图的顶部狭长部分用作该行的可单击标题

然后将此类作为
UITableView
的数据源和委托

头文件
collasingTableViewDelegate.h

#import <UIKit/UIKit.h>

@protocol CollapsingTableCellDelegate<NSObject>

@required
- (CGFloat)collapsingCellHeightForRow:(int)row expanded:(BOOL)expanded;
- (UIView *)collapsingCellViewForRow:(int)row;

@optional
- (BOOL)collapsingCellAllowCollapse:(int)row;

@end

struct cell;

@interface CollapsingTableViewDelegate : NSObject <UITableViewDelegate, UITableViewDataSource> {
    id<CollapsingTableCellDelegate> cellDelegate;
    int numCells;
    int currentSelection;
    struct cell *cells;
}

@property (nonatomic, retain, readonly) id<CollapsingTableCellDelegate> cellDelegate;
@property (nonatomic, assign, readonly) int numCells;
@property (nonatomic, assign) int currentSelection;
@property (nonatomic, assign, readonly) struct cell *cells;

- (CollapsingTableViewDelegate *)initWithCellDelegate:(id<CollapsingTableCellDelegate>)delegate numCells:(int)numCells;
- (void)tableView:(UITableView *)tableView touchRow:(int)newSelection;

@end

不是十全十美,但似乎基本上对我有用。

如果有人感兴趣,我在这里找到了这个例子


我找到的每个解决方案都使用UITableView,但它对我不起作用,因为我没有显示表格数据。这就是我创建控件的原因。用法非常简单:

AccordionView *accordion = [[AccordionView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
[self addSubview:accordion];

// Only height is taken into account, so other parameters are just dummy
UIButton *header1 = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 30)];
[header1.titleLabel setText:@"First row"];

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
// ... add subviews to view1

[accordion addHeader:header1 withView:view1];

// ... add more panels

[accordion setSelectedIndex:0];
在现实生活中,它看起来是这样的:


黑条是标题,您可以自定义它们(我使用的是Three20)。

我发现了以下代码:一个简单的accordion实现


我希望这会对某些人有所帮助。

看看它为iPad实现了手风琴式导航,在那里你可以看到一切是如何工作的@雅各布:不是一切都可能!(见)这个手风琴样品有真正的潜力。我尝试了一下,发现使用UITableView单元格可以提供非常平滑的过渡和手风琴般的感觉。我建议更改-(void)fileAccordionDatasourceManager:(N4FileAccordionDatasourceManager*)管理器DidInsertRowsAndExpaths:(NSArray*)indexPaths{/[self.tableView InsertRowsAndExpaths:indexPaths with RowAnimation:UITableViewRowAnimationLeft];[self.tableView insertRowsAtIndexPaths:indexPaths with rownanimation:uitableview rownanimationtop];这是完美的答案。效果非常好……嗨,苏达,谢谢你的控制。我在使用它时遇到了一个小问题。我在project的Github上打开了一个问题。你能看一下吗?嗨,苏达,非常感谢你的工作。这里我打开了一个小问题。请看一看。
AccordionView *accordion = [[AccordionView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
[self addSubview:accordion];

// Only height is taken into account, so other parameters are just dummy
UIButton *header1 = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 30)];
[header1.titleLabel setText:@"First row"];

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
// ... add subviews to view1

[accordion addHeader:header1 withView:view1];

// ... add more panels

[accordion setSelectedIndex:0];