我有一个带有几个部分的UITableView。 我想点击一个部分来“关闭/打开”它的内容,以显示/隐藏它下面的行。这样,我可以保持一些部分打开(其行可见),其他部分关闭,下一部分紧接在上一部分标题下面。
我该如何实施?我是否需要继承UITableView并添加手势识别器并以某种方式向行添加动画?但我不确定这很容易......
感谢
答案 0 :(得分:0)
我无法对这个问题发表评论,因为我没有足够的声誉。
根据我的理解,您希望为您的桌面视图实现手风琴功能。
为此,请检查: - effect or animation in UItableVIew和
How to implement an accordion view for an iPhone SDK app?
答案 1 :(得分:0)
reloadSections:withRowAnimation
触发更改; 答案 2 :(得分:0)
只需继承sectionHeaderView并定义这样的委托方法。
@protocol SectionHeaderViewDelegate <NSObject>
@optional
-(void)sectionHeaderView:(SectionHeaderView*)sectionHeaderView sectionOpened:(NSInteger)section;
-(void)sectionHeaderView:(SectionHeaderView*)sectionHeaderView sectionClosed:(NSInteger)section;
@end
然后在tableViewCOntroller.h
中@interface TableViewController : UITableViewController <SectionHeaderViewDelegate>
并在tableViewCOntroller.m
中-(void)sectionHeaderView:(SectionHeaderView*)sectionHeaderView sectionOpened:(NSInteger)sectionOpened
{
SectionInfo *sectionInfo = [self.sectionInfoArray objectAtIndex:sectionOpened];
sectionInfo.open = YES;
/*
Create an array containing the index paths of the rows to insert: These correspond to the rows for each quotation in the current section.
*/
NSInteger countOfRowsToInsert = [sectionInfo.play.quotations count];
NSMutableArray *indexPathsToInsert = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < countOfRowsToInsert; i++) {
[indexPathsToInsert addObject:[NSIndexPath indexPathForRow:i inSection:sectionOpened]];
}
/*
Create an array containing the index paths of the rows to delete: These correspond to the rows for each quotation in the previously-open section, if there was one.
*/
NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
NSInteger previousOpenSectionIndex = self.openSectionIndex;
if (previousOpenSectionIndex != NSNotFound) {
SectionInfo *previousOpenSection = [self.sectionInfoArray objectAtIndex:previousOpenSectionIndex];
previousOpenSection.open = NO;
[previousOpenSection.headerView toggleOpenWithUserAction:NO];
NSInteger countOfRowsToDelete = [previousOpenSection.play.quotations count];
for (NSInteger i = 0; i < countOfRowsToDelete; i++) {
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:previousOpenSectionIndex]];
}
}
// Style the animation so that there's a smooth flow in either direction.
UITableViewRowAnimation insertAnimation;
UITableViewRowAnimation deleteAnimation;
if (previousOpenSectionIndex == NSNotFound || sectionOpened < previousOpenSectionIndex) {
insertAnimation = UITableViewRowAnimationTop;
deleteAnimation = UITableViewRowAnimationBottom;
}
else {
insertAnimation = UITableViewRowAnimationBottom;
deleteAnimation = UITableViewRowAnimationTop;
}
// Apply the updates.
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPathsToInsert withRowAnimation:insertAnimation];
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:deleteAnimation];
[self.tableView endUpdates];
self.openSectionIndex = sectionOpened;
}
-(void)sectionHeaderView:(SectionHeaderView*)sectionHeaderView sectionClosed:(NSInteger)sectionClosed
{
/*
Create an array of the index paths of the rows in the section that was closed, then delete those rows from the table view.
*/
SectionInfo *sectionInfo = [self.sectionInfoArray objectAtIndex:sectionClosed];
sectionInfo.open = NO;
NSInteger countOfRowsToDelete = [self.tableView numberOfRowsInSection:sectionClosed];
if (countOfRowsToDelete > 0)
{
NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < countOfRowsToDelete; i++) {
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:sectionClosed]];
}
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:UITableViewRowAnimationTop];
}
self.openSectionIndex = NSNotFound;
if ([selectedIndexes count]>0)
{
for(NSIndexPath *indexPath in selectedIndexes)
{
if(sectionClosed == indexPath.section)
{
[sectionInfo.headerView changeOnHighlighted:YES];
break;
}
else
{
[sectionInfo.headerView changeOnHighlighted:NO];
}
}
}
else
{
[sectionInfo.headerView changeOnHighlighted:NO];
}
}
有关详细信息,您可以参考iOS开发中的sample project。
答案 3 :(得分:0)
这是一个简单的解决方案,您甚至可以通过它创建自定义展开/折叠视图。 这里是简单的一步 1)在其上创建自定义视图添加按钮。 /// 加入所有插座并在视图类
中创建BOOL变量@property (weak, nonatomic) IBOutlet UIButton *BtnAction;
@property(assign, nonatomic)BOOL isOpen;
//创建一个标题,其中添加了tableview并且您想要它。 这是一个简单的逻辑,可以根据需要添加。我添加了哪些是headertitle数组,我希望它是动态的。
NSMutableArray * headerTitle = [NSMutableArray arrayWithObjects:@"Your Order", @"Delivery Address", @"Pay By", nil];
for (NSUInteger index = 0; index<headerTitle.count; index++) {
VGOrderHeader* HeaderView = [[[NSBundle mainBundle] loadNibNamed:@"VGOrderHeader" owner:self options:nil] lastObject];
HeaderView.frame = CGRectMake(0, 0, 32, 40);
HeaderView.BtnAction.tag = index;
if (index == 0) {
HeaderView.isOpen = YES;
HeaderView.lblPlus.text = [NSString stringWithFormat:@"open"];
}
[HeaderView.BtnAction addTarget:self action:@selector(selectSectionToOpen:) forControlEvents:UIControlEventTouchUpInside];
[headerArray addObject:HeaderView];
}
///这是标题点击操作。
-(void)selectSectionToOpen:(UIButton *)sender{
for (NSUInteger Increment=0; Increment<headerArray.count; Increment++) {
if (sender.tag == Increment) {
DCOrderHeader* HeaderView= headerArray[Increment];
HeaderView.isOpen = !HeaderView.isOpen;
}
}
// little animation
dispatch_async(dispatch_get_main_queue(), ^{
[UIView transitionWithView:self.tableView
duration:0.55f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^(void) {
[self.tableView reloadData];
} completion:NULL];
});
}
///最后在表视图的header方法中指定视图并提供高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 40;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [headerArray objectAtIndex:section];
}
// Final Touch
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return headerArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
DCOrderHeader* HeaderView = headerArray[section];
if (HeaderView.isOpen == YES) {
return self.someArray.count;
}else{
return 0;
}
}