代码之家  ›  专栏  ›  技术社区  ›  sia

具有行展开和折叠选项的表视图的最佳方法

  •  2
  • sia  · 技术社区  · 9 年前

    我有一个包含tableview和searchbar的视图。当我开始搜索时,它应该搜索表视图。以下是附加图像中tableview的示例数据: enter image description here

    学生1、学生2是表格中的不同部分

    假设我搜索“S”,则结果应如下所示,其中匹配的行应可见,不匹配的行-应隐藏,并且“显示剩余”按钮应可见。当我点击“显示剩余”按钮时,它应该显示同一部分的剩余行:

    enter image description here

    3 回复  |  直到 9 年前
        1
  •  2
  •   Ramkrishna Sharma    9 年前

    我已经为您的需求创建了代码。请找到下面的url下载代码并查看它。

    链接: https://www.dropbox.com/s/22ijwgxybn98wyj/ExpandCollapse.zip?dl=0

    环境:Xcode 8和Objective-C

    突出显示我所做的代码。

    我已经根据您的结构创建了学生的NSObject,创建了两个(StudentListCell和ShowMoreCell) UITableViewCell 用于显示学生记录和“显示剩余按钮”记录。

    此外,我还采取了两个(arrStudentInfo,arrSearchInfo) NSMutablebleArray

    之后,我在中初始化学生的NSObject ViewController.m

    - (void)setupData {
    
        self.arrStudentInfo = [[NSMutableArray alloc] init];
        self.arrSearchInfo = [[NSMutableArray alloc] init];
    
        StudentInfo *student_1 = [[StudentInfo alloc] init];
        student_1.name = @"Sia S";
        student_1.style = @"S";
        student_1.trend = @"S";
        student_1.age = @"60";
        student_1.locale = @"Node";
        student_1.street = @"BR";
        student_1.city = @"JP";
        student_1.country = @"US";
        student_1.isOpen = YES;
        student_1.isShowMore = NO;
        [self.arrStudentInfo addObject:student_1];
    
        StudentInfo *student_2 = [[StudentInfo alloc] init];
        student_2.name = @"Nitin";
        student_2.style = @"N";
        student_2.trend = @"N";
        student_2.age = @"40";
        student_2.locale = @"Node";
        student_2.street = @"BR";
        student_2.city = @"SP";
        student_2.country = @"US";
        student_2.isOpen = YES;
        student_2.isShowMore = NO;
        [self.arrStudentInfo addObject:student_2];
    }
    

    我已经创建了返回当前活动的方法,这意味着搜索记录或数组的原始记录。

    - (NSMutableArray *)getCurrentArray {
    
        if(self.isSearch)
            return self.arrSearchInfo;
        else
            return self.arrStudentInfo;
    }
    

    基于场景加载数据,

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        StudentInfo *studentInfo = [self getCurrentArray][indexPath.section];
    
        if(indexPath.row == SHOW_MORE_INDEX && studentInfo.isShowMore == NO) {
    
            static NSString *strCellIdentifier = @"ShowMoreCell";
            ShowMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:strCellIdentifier];
            cell.btnShowMore.tag = indexPath.section;
            [cell.btnShowMore addTarget:self action:@selector(clickONShowMore:) forControlEvents:UIControlEventTouchUpInside];
    
            return cell;
        }
    
        else {
    
            static NSString *strCellIdentifier = @"StudentListCell";
    
            StudentListCell *cell = [tableView dequeueReusableCellWithIdentifier:strCellIdentifier];
            [cell setupCell:studentInfo indexPath:indexPath];
    
            return cell;
        }
    }
    

    为了搜索学生姓名,

    - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    
        [searchBar resignFirstResponder];
        self.isSearch = YES;
    
        NSPredicate *predicateStudent = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"self.name CONTAINS[cd] '%@'",searchBar.text]];
        NSArray *arrGetSearch = [self.arrStudentInfo filteredArrayUsingPredicate:predicateStudent];
    
        if(self.arrSearchInfo.count)
            [self.arrSearchInfo removeAllObjects];
    
        [self.arrSearchInfo addObjectsFromArray:arrGetSearch];
        [self.tblView reloadData];
    }
    

    如果用户单击“X”按钮,则再次加载原始记录 UISearchbar .

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    
        if([searchText isEqualToString:@""] || searchText==nil) {
    
            [searchBar resignFirstResponder];
            self.isSearch = NO;
            [self.tblView reloadData];
        }
    }
    

    希望这对你有用。

        2
  •  1
  •   Hasya    9 年前

    有许多示例可用于展开和折叠表。

    您可以参考下面的示例

    http://www.appcoda.com/expandable-table-view/

    通过在plist文件中动态设置。您可以维护可扩展和可折叠的tableview。

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
        let cell = tableView.dequeueReusableCellWithIdentifier(currentCellDescriptor["cellIdentifier"] as! String, forIndexPath: indexPath) as! CustomCell
    
        if currentCellDescriptor["cellIdentifier"] as! String == "idCellNormal" {
            if let primaryTitle = currentCellDescriptor["primaryTitle"] {
                cell.textLabel?.text = primaryTitle as? String
            }
    
            if let secondaryTitle = currentCellDescriptor["secondaryTitle"] {
                cell.detailTextLabel?.text = secondaryTitle as? String
            }
        }
        else if currentCellDescriptor["cellIdentifier"] as! String == "idCellTextfield" {
            cell.textField.placeholder = currentCellDescriptor["primaryTitle"] as? String
        }
        else if currentCellDescriptor["cellIdentifier"] as! String == "idCellSwitch" {
            cell.lblSwitchLabel.text = currentCellDescriptor["primaryTitle"] as? String
    
            let value = currentCellDescriptor["value"] as? String
            cell.swMaritalStatus.on = (value == "true") ? true : false
        }
        else if currentCellDescriptor["cellIdentifier"] as! String == "idCellValuePicker" {
            cell.textLabel?.text = currentCellDescriptor["primaryTitle"] as? String
        }
        else if currentCellDescriptor["cellIdentifier"] as! String == "idCellSlider" {
            let value = currentCellDescriptor["value"] as! String
            cell.slExperienceLevel.value = (value as NSString).floatValue
        }
    
        return cell
    }
    
        3
  •  1
  •   Sergii Martynenko Jr    9 年前

    在UITableView中,我想不出任何通用的“最佳方法”来崩溃/扩展行为。我怀疑这就是苹果没有提供信息的原因。相反,他们给了我们足够的工具,以我们希望的方式实施它。

    在你的特殊情况下,我有下一个愿景。 我不知道,也不需要知道,您如何准确地处理任务的模型端,下面的代码仅用于这个答案的目的,即-为您提供您所寻求的崩溃行为。

    我建议以这种方式实施您想要的行为。在ViewController中,可以控制搜索栏和表视图添加字段

    @property NSArray* filteredStudents;
    @property NSMutableIndexSet* expandedStudents;
    

    当没有进行搜索时,这些属性将为nil(或空实例)。一旦搜索开始(输入第一个符号或点击“搜索”按钮-无论您最喜欢什么)-实例化它们。

    filteredStudents -数组,该数组包含对满足搜索条件的学生的引用。它在每次执行搜索时更新。每次更新时,执行[tableView reloadData]。

    expandedStudents -索引集,告诉您用户在哪些节中按下了“全部显示”。别忘了-它只包含部分编号。那么,什么时候 筛选学生 数组更改时,必须手动更新。例如,当您输入“S”时,会显示两个学生。你在第二个学生身上按“全部显示”。 expandStudents 现在有了一个数字 1 在里面。然后输入“Se”,只剩下第二个学生。在这种情况下,你必须更换 1. 在里面 扩展学生 具有 0 因为第二个学生的部分变成了第一个。

    另一财产

     @property BOOL searchMode;
    

    无论何时显示筛选结果,此属性都应为“是”。不,否则。

    接下来,修改UITableViewDataSource和委托方法,如下所示

    - (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
        if(searchMode) {
           return self.filteredStudents.count;
        }
        else {
           //Your current behaviour here
        }
    }
    
    - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        if(searchMode) {
           if([self.expandedStudents containsIndex:section]) { // Button "Show all" was already tapped for this student
              return /* Number of all fields you need to show for student. Just like you do now. It is for expanded section */
           }
           else {
               return /* Number of fields that satisfy search criteria for student self.filteredStudents[section] */
           }
        }
        else {
           //Your current behaviour here
        }
    }
    
    - (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        if(searchMode) {
            if(![self.expandedStudents containsIndex:section] && /* indexPath corresponds to place, where "Show All" should be */) {
               //Create "Show All" cell
            }
            else {
              //Create cell that contains info from filtered student fields
            }
        }
        else {
           //Your current behaviour here
        }
    }
    
    - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
       if(searchMode && ![self.expandedStudents containsIndex:section] && /* indexPath corresponds to place, where "Show All" should be */) {
          //"Show All" button pressed
          [self.expandedStudents addIndex:indexPath.section];
    
          [tableView beginUpdates];
          /* For each row, that wasn't presented in collapsed student perform insertRowsAtIndexPaths:withRowAnimation: method */
          [tableView endUpdates];
       }
       else {
          //Your current behaviour
       }
    }