具有行展开和折叠选项的tableview的最佳方法

时间:2016-10-20 10:59:25

标签: ios objective-c uitableview tableview customization

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

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

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

enter image description here

我如何实现这一目标,如果可能,请提供上述情况的示例。

3 个答案:

答案 0 :(得分:2)

我已根据您的要求创建了代码,请找到以下网址下载代码并进行审核。

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

  

环境:Xcode 8和Objective-C

突出显示我已经完成的代码。

我根据你的结构创建了学生的NSObject,创建了两个(StudentListCell和ShowMoreCell)UITableViewCell来显示学生的记录和#34;显示剩余按钮"记录。

此外,我还使用了两个(arrStudentInfo,arrSearchInfo)NSMutablebleArray来保存搜索记录和原始记录。

之后,我在ViewController.m中启动学生的NSObject。请找到以下代码。

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

希望这对你有用。

答案 1 :(得分:1)

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

您可以参考以下示例

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

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

    public class YourSingleton  {  

        private static YourSingleton mInstance;
        private ArrayList<String> list = null;

        public static YourSingleton getInstance() {
            if(mInstance == null)
                mInstance = new YourSingleton();

            return mInstance;
        }

        private YourSingleton() {
          list = new ArrayList<String>();
        }
        // retrieve array from anywhere
        public ArrayList<String> getArray() {
         return this.list;
        }
        //Add element to array
        public void addToArray(String value) {
         list.add(value);
        }
}

答案 2 :(得分:1)

我无法想到在UITableView中折叠/扩展行为的任何一般“最佳方法”。我怀疑这就是Apple没有提供的原因。相反,他们给了我们足够的工具,以我们希望的方式实施它。

在您的特定情况下,我有下一个愿景。 我不知道,也不需要知道,你究竟是如何使用你的任务的模型方面的,以下代码仅用于这个答案的目的,即为你提供你所寻求的崩溃行为。

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

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

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

filteredStudents - 保存对那些学生的引用的数组,满足您的搜索条件。每次执行搜索时都会更新。每次更新时 - 执行[tableView reloadData]。

expandedStudents - 索引集,告诉您哪些部分的用户按下了“全部显示”。不要忘记 - 它只保留部分编号。因此,当filteredStudents数组更改时,您必须手动更新它。例如,当您输入“S”时 - 您显示了两名学生。你按下第二个学生的全部显示。 expandStudents现在有1个号码。比你输入“Se”,只剩下第二个学生。在这种情况下,您必须将1中的expandedStudents替换为0,因为第二个学生的部分会成为第一个。

另一个属性

 @property BOOL searchMode;

只要显示过滤结果,此属性就应为YES。不 - 否则。

接下来,修改像这样的UITableViewDataSource和Delegate方法

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