当前位置:  开发笔记 > 前端 > 正文

在iOS中的UITableView中展开/折叠部分

如何解决《在iOS中的UITableView中展开/折叠部分》经验,为你挑选了7个好方法。

有人能告诉我的执行方式UITableView的展开/折叠动画sectionsUITableView下面?

要么



1> mjdth..:

您必须创建自己的自定义标题行,并将其作为每个部分的第一行.对UITableView已经存在的标题进行子类化将会很痛苦.根据他们现在的工作方式,我不确定您是否可以轻松地采取行动.您可以将单元格设置为LOOK,如标题,并设置tableView:didSelectRowAtIndexPath为手动展开或折叠它所在的部分.

我会存储一系列布尔值,这些布尔值对应于每个部分的"消耗"值.然后,您可以tableView:didSelectRowAtIndexPath在每个自定义标题行上切换此值,然后重新加载该特定部分.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 0) {
        ///it's the first row of any section so it would be your custom section header

        ///put in your code to toggle your boolean value here
        mybooleans[indexPath.section] = !mybooleans[indexPath.section];

        ///reload this section
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
    }
}

然后设置numberOfRowsInSection为检查mybooleans值,如果未展开部分则返回1,如果展开部分,则返回1 +项目中的项目数.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (mybooleans[section]) {
        ///we want the number of people plus the header cell
        return [self numberOfPeopleInGroup:section] + 1;
    } else {
        ///we just want the header cell
        return 1;
    }
}

此外,您还需要更新cellForRowAtIndexPath以返回任何部分中第一行的自定义标题单元格.


` - (UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section`是提供"自己的自定义标题"的更好方法,因为它正是它的设计目的.
如果你已经使用过Beejive应用程序,你就会知道他们的可折叠部分标题实际上是"浮动"在表的顶部,即使你滚动浏览部分部分,就像常规的Apple部分标题一样.如果您只是在该部分的开头添加一个单元格,那是不可能的

2> samwize..:

Apple提供了一些使用表格视图部分标题动画展开/折叠动作的示例代码:Table View Animations and Gestures

这种方法的关键是实现- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section并返回一个自定义UIView,它包含一个按钮(通常与标题视图本身的大小相同).通过子类化UIView并将其用于标题视图(如此示例所示),您可以轻松存储其他数据,例如节号.


太棒了,谢谢:http://developer.apple.com/library/ios/#samplecode/TableViewUpdates/Introduction/Intro.html

3> Brian..:

我得到了一个很好的解决方案,灵感来自Apple的Table View Animations和Gestures.我从Apple的样本中删除了不必要的部分并将其翻译成swift.

我知道答案很长,但所有代码都是必要的.幸运的是,您可以复制并覆盖大部分代码,只需要对步骤1和3进行一些修改即可

创造SectionHeaderView.swiftSectionHeaderView.xib

import UIKit

protocol SectionHeaderViewDelegate {
    func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionOpened: Int)
    func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionClosed: Int)
}

class SectionHeaderView: UITableViewHeaderFooterView {

    var section: Int?
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var disclosureButton: UIButton!
    @IBAction func toggleOpen() {
        self.toggleOpenWithUserAction(true)
    }
    var delegate: SectionHeaderViewDelegate?

    func toggleOpenWithUserAction(userAction: Bool) {
        self.disclosureButton.selected = !self.disclosureButton.selected

        if userAction {
            if self.disclosureButton.selected {
                self.delegate?.sectionHeaderView(self, sectionClosed: self.section!)
            } else {
                self.delegate?.sectionHeaderView(self, sectionOpened: self.section!)
            }
        }
    }

    override func awakeFromNib() {
        var tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "toggleOpen")
        self.addGestureRecognizer(tapGesture)
        // change the button image here, you can also set image via IB.
        self.disclosureButton.setImage(UIImage(named: "arrow_up"), forState: UIControlState.Selected)
        self.disclosureButton.setImage(UIImage(named: "arrow_down"), forState: UIControlState.Normal)
    }

}

SectionHeaderView.xib(与灰色背景视图)应该是这个样子的实现代码如下(你可以根据自己的需要定制它,当然): 在此输入图像描述

注意:

a)该toggleOpen行动应与之相关联disclosureButton

二)disclosureButtontoggleOpen动作是没有必要的.如果您不需要按钮,可以删除这两件事.

2.创建 SectionInfo.swift

import UIKit

class SectionInfo: NSObject {
    var open: Bool = true
    var itemsInSection: NSMutableArray = []
    var sectionTitle: String?

    init(itemsInSection: NSMutableArray, sectionTitle: String) {
        self.itemsInSection = itemsInSection
        self.sectionTitle = sectionTitle
    }
}

在你的桌面视图中

import UIKit

class TableViewController: UITableViewController, SectionHeaderViewDelegate  {

    let SectionHeaderViewIdentifier = "SectionHeaderViewIdentifier"

    var sectionInfoArray: NSMutableArray = []

    override func viewDidLoad() {
        super.viewDidLoad()

        let sectionHeaderNib: UINib = UINib(nibName: "SectionHeaderView", bundle: nil)
        self.tableView.registerNib(sectionHeaderNib, forHeaderFooterViewReuseIdentifier: SectionHeaderViewIdentifier)

        // you can change section height based on your needs
        self.tableView.sectionHeaderHeight = 30

        // You should set up your SectionInfo here
        var firstSection: SectionInfo = SectionInfo(itemsInSection: ["1"], sectionTitle: "firstSection")
        var secondSection: SectionInfo = SectionInfo(itemsInSection: ["2"], sectionTitle: "secondSection"))
        sectionInfoArray.addObjectsFromArray([firstSection, secondSection])
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return sectionInfoArray.count
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.sectionInfoArray.count > 0 {
            var sectionInfo: SectionInfo = sectionInfoArray[section] as! SectionInfo
            if sectionInfo.open {
                return sectionInfo.open ? sectionInfo.itemsInSection.count : 0
            }
        }
        return 0
    }

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let sectionHeaderView: SectionHeaderView! = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier(SectionHeaderViewIdentifier) as! SectionHeaderView
        var sectionInfo: SectionInfo = sectionInfoArray[section] as! SectionInfo

        sectionHeaderView.titleLabel.text = sectionInfo.sectionTitle
        sectionHeaderView.section = section
        sectionHeaderView.delegate = self
        let backGroundView = UIView()
        // you can customize the background color of the header here
        backGroundView.backgroundColor = UIColor(red:0.89, green:0.89, blue:0.89, alpha:1)
        sectionHeaderView.backgroundView = backGroundView
        return sectionHeaderView
    }

    func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionOpened: Int) {
        var sectionInfo: SectionInfo = sectionInfoArray[sectionOpened] as! SectionInfo
        var countOfRowsToInsert = sectionInfo.itemsInSection.count
        sectionInfo.open = true

        var indexPathToInsert: NSMutableArray = NSMutableArray()
        for i in 0.. 0 {
            var indexPathToDelete: NSMutableArray = NSMutableArray()
            for i in 0..



4> jeantimex..:

要在iOS中实现可折叠表部分,神奇的是如何控制每个部分的行数,或者我们可以管理每个部分的行高.

此外,我们需要自定义节标题,以便我们可以从标题区域(无论是按钮还是整个标题)监听点击事件.

如何处理标题?这很简单,我们扩展UITableViewCell类并制作一个自定义标题单元格,如下所示:

import UIKit

class CollapsibleTableViewHeader: UITableViewCell {

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var toggleButton: UIButton!

}

然后使用viewForHeaderInSection挂接标题单元格:

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  let header = tableView.dequeueReusableCellWithIdentifier("header") as! CollapsibleTableViewHeader

  header.titleLabel.text = sections[section].name
  header.toggleButton.tag = section
  header.toggleButton.addTarget(self, action: #selector(CollapsibleTableViewController.toggleCollapse), forControlEvents: .TouchUpInside)

  header.toggleButton.rotate(sections[section].collapsed! ? 0.0 : CGFloat(M_PI_2))

  return header.contentView
}

记住我们必须返回contentView,因为这个函数需要返回一个UIView.

现在让我们来处理可折叠部分,这里是切换每个部分的可折叠道具的切换功能:

func toggleCollapse(sender: UIButton) {
  let section = sender.tag
  let collapsed = sections[section].collapsed

  // Toggle collapse
  sections[section].collapsed = !collapsed

  // Reload section
  tableView.reloadSections(NSIndexSet(index: section), withRowAnimation: .Automatic)
}

取决于你如何管理部分数据,在这种情况下,我有这样的部分数据:

struct Section {
  var name: String!
  var items: [String]!
  var collapsed: Bool!

  init(name: String, items: [String]) {
    self.name = name
    self.items = items
    self.collapsed = false
  }
}

var sections = [Section]()

sections = [
  Section(name: "Mac", items: ["MacBook", "MacBook Air", "MacBook Pro", "iMac", "Mac Pro", "Mac mini", "Accessories", "OS X El Capitan"]),
  Section(name: "iPad", items: ["iPad Pro", "iPad Air 2", "iPad mini 4", "Accessories"]),
  Section(name: "iPhone", items: ["iPhone 6s", "iPhone 6", "iPhone SE", "Accessories"])
]

最后,我们需要做的是基于每个部分的可折叠道具,控制该部分的行数:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  return (sections[section].collapsed!) ? 0 : sections[section].items.count
}

我在我的Github上有一个完整的演示程序:https://github.com/jeantimex/ios-swift-collapsible-table-section

演示

如果你想在分组式表格中实现可折叠部分,我在这里有另一个带有源代码的演示:https://github.com/jeantimex/ios-swift-collapsible-table-section-in-grouped-section

希望有所帮助.



5> Son Nguyen..:

我有一个更好的解决方案,您应该将UIButton添加到节标题中,并将此按钮的大小设置为等于节大小,但是将其隐藏为明确的背景颜色,之后您可以轻松检查单击哪个节点以展开或折叠


在我看来,这个解决方案比接受的答案要好,因为在语义上你将标题保留为标题,并且不使用假行来模拟标题.方法`tableView:numberOfRowsInSection:`将不受影响,您将继续能够将它用于它的真正含义.`tableView:cellForRowAtIndexPath:`也是如此.

6> RyanG..:

我最后只是创建了一个包含一个按钮的headerView(事后我看到了Son Nguyen的解决方案,但是我的代码......看起来很多,但很简单):

为你的部分宣布一对bool

bool customerIsCollapsed = NO;
bool siteIsCollapsed = NO;

...码

现在在你的tableview委托方法中......

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _tblSearchResults.frame.size.width, 35)];

    UILabel *lblSection = [UILabel new];
    [lblSection setFrame:CGRectMake(0, 0, 300, 30)];
    [lblSection setFont:[UIFont fontWithName:@"Helvetica-Bold" size:17]];
    [lblSection setBackgroundColor:[UIColor clearColor]];
    lblSection.alpha = 0.5;
    if(section == 0)
    {
        if(!customerIsCollapsed)
            [lblSection setText:@"Customers    --touch to show--"];
        else
            [lblSection setText:@"Customers    --touch to hide--"];
    }
    else
    {
        if(!siteIsCollapsed)
            [lblSection setText:@"Sites    --touch to show--"];
        else
            [lblSection setText:@"Sites    --touch to hide--"];    }

    UIButton *btnCollapse = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnCollapse setFrame:CGRectMake(0, 0, _tblSearchResults.frame.size.width, 35)];
    [btnCollapse setBackgroundColor:[UIColor clearColor]];
    [btnCollapse addTarget:self action:@selector(touchedSection:) forControlEvents:UIControlEventTouchUpInside];
    btnCollapse.tag = section;


    [headerView addSubview:lblSection];
    [headerView addSubview:btnCollapse];

    return headerView;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    if(section == 0)
    {
        if(customerIsCollapsed)
            return 0;
        else
            return _customerArray.count;
    }
    else if (section == 1)
    {
        if(siteIsCollapsed)
            return 0;
        else
        return _siteArray.count;

    }
    return 0;
}

最后触摸其中一个节标题按钮时调用的函数:

- (IBAction)touchedSection:(id)sender
{
    UIButton *btnSection = (UIButton *)sender;

    if(btnSection.tag == 0)
    {
        NSLog(@"Touched Customers header");
        if(!customerIsCollapsed)
            customerIsCollapsed = YES;
        else
            customerIsCollapsed = NO;

    }
    else if(btnSection.tag == 1)
    {
        NSLog(@"Touched Site header");
        if(!siteIsCollapsed)
            siteIsCollapsed = YES;
        else
            siteIsCollapsed = NO;

    }
    [_tblSearchResults reloadData];
}



7> vamsi575kg..:

这是我发现创建可扩展表视图单元格的最佳方法

.h文件

  NSMutableIndexSet *expandedSections;

.m文件

if (!expandedSections)
    {
        expandedSections = [[NSMutableIndexSet alloc] init];
    }
   UITableView *masterTable = [[UITableView alloc] initWithFrame:CGRectMake(0,100,1024,648) style:UITableViewStyleGrouped];
    masterTable.delegate = self;
    masterTable.dataSource = self;
    [self.view addSubview:masterTable];

表视图委托方法

- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
{
    // if (section>0) return YES;

    return YES;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 4;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if ([self tableView:tableView canCollapseSection:section])
    {
        if ([expandedSections containsIndex:section])
        {
            return 5; // return rows when expanded
        }

        return 1; // only top row showing
    }

    // Return the number of rows in the section.
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
    }

    // Configure the cell...

    if ([self tableView:tableView canCollapseSection:indexPath.section])
    {
        if (!indexPath.row)
        {
            // first row
            cell.textLabel.text = @"Expandable"; // only top row showing

            if ([expandedSections containsIndex:indexPath.section])
            {

                UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableContract"]];
                cell.accessoryView = imView;
            }
            else
            {

                UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableExpand"]];
                cell.accessoryView = imView;
            }
        }
        else
        {
            // all other rows
            if (indexPath.section == 0) {
                cell.textLabel.text = @"section one";
            }else if (indexPath.section == 1) {
                cell.textLabel.text = @"section 2";
            }else if (indexPath.section == 2) {
                cell.textLabel.text = @"3";
            }else {
                cell.textLabel.text = @"some other sections";
            }

            cell.accessoryView = nil;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
    }
    else
    {
        cell.accessoryView = nil;
        cell.textLabel.text = @"Normal Cell";

    }

    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self tableView:tableView canCollapseSection:indexPath.section])
    {
        if (!indexPath.row)
        {
            // only first row toggles exapand/collapse
            [tableView deselectRowAtIndexPath:indexPath animated:YES];

            NSInteger section = indexPath.section;
            BOOL currentlyExpanded = [expandedSections containsIndex:section];
            NSInteger rows;


            NSMutableArray *tmpArray = [NSMutableArray array];

            if (currentlyExpanded)
            {
                rows = [self tableView:tableView numberOfRowsInSection:section];
                [expandedSections removeIndex:section];

            }
            else
            {
                [expandedSections addIndex:section];
                rows = [self tableView:tableView numberOfRowsInSection:section];
            }


            for (int i=1; i


您应该将问题标记为完全重复,而不是仅仅在所有问题上发送相同的答案.
推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有