【问题标题】:Reuse Storyboard viewcontrollers重用 Storyboard 视图控制器
【发布时间】:2017-01-20 08:04:44
【问题描述】:

我正在重建一个需要显示项目列表的应用程序。此列表使用 API 检索或从 Core Data 检索并显示在 UITableViewController 中。我遇到的问题是已经有七个不同的列表存在细微差异。它们中的大多数只是不同的项目,但一个列表中包含的搜索栏和前面提到的一个列表不会使用 API 加载,而是从 Core Data 加载。

在我的 Storyboard 中,我添加了一个 UITableViewController,它带有一个设计好的 UITableViewCell 类 ItemsTableViewController。我已经向这个单元格添加了一个标识符,所以我可以在这个视图控制器中重用它。从主屏幕到这个视图控制器有一个 segue。

这个想法是创建一个父对象(ItemsTableViewController)并添加多个子对象(SavedItemsTableViewController、LocalItemsTableViewController 等),它们都将使用父对象的共享逻辑,只需进行一些小的更改(API 和一些自定义的东西)。

我目前拥有的是工作,但没有子对象:

- (void)offlineButtonPressed {
    [self performSegueWithIdentifier:@"openItemsTableViewController" sender:@(ItemListOffline)];
    //[[self navigationController] pushViewController:[[OfflineItemsTableViewController alloc] init] animated:YES];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"openItemsTableViewController"]) {
        switch((ItemList)[sender unsignedIntegerValue]) {
            case ItemListOffline: { [(ItemsTableViewController *)[segue destinationViewController] retrieveOfflineDocuments]; break; }
            case ItemListSearch: {
                [(ItemsTableViewController *)[segue destinationViewController] retrieveDocumentsWithQuery:@""];
                [(ItemsTableViewController *)[segue destinationViewController] addSearchBar];
                break;
            }
            // Loop through all the list...
            default: { NSAssert(NO, @"Unhandled type of document list."); break; }
        }
    }
}

所以应用程序只是调用处理请求的父对象的一个​​函数。但正如您可能感觉到的那样,该对象的可维护性会降低。在 cmets 中我推送了子视图控制器,但由于它不包含情节提要视图,因此我需要从头开始重新创建单元格,这感觉不太好。另外,由于重用标识符,它无法使用 tableView:cellForRowAtIndexPath: 方法中设置的标识符将单元格出列。

现在我想知道最好的做法是什么?看来我不能将情节提要中的保存 UITableViewController 用于多个子类,可以吗?但是在情节提要中创建七个(将来可能会更多)控制器,我需要将单元复制到每个控制器并只给它们不同的类似乎不是这样做的方法。并向父级添加一个方法,以不同的方式检索列表并更改一些东西,例如添加搜索栏,但它似乎不是最好的方式。

更新:ItemsTableViewController 中的逻辑非常简单。在委托和数据源中,我处理的文档几乎相同。检索每个列表类型的方法类似于:

- (void)retrieveOfflineItems {
    [self startLoading];

    [[APIManager instance] getOfflineItems:^(NSArray<ItemList *> *list, NSError *error) {
        [self setDocuments:list];
        [[self tableView] reloadData];
    }];
}

但是还有更多的东西,比如搜索必须添加一个搜索栏(一旦加载视图)。所以在执行segue的时候需要调用多个方法。

【问题讨论】:

    标签: ios objective-c uitableview storyboard


    【解决方案1】:

    您可以有一个UITableViewController,其中包括所有您可能的表格单元格,并且作为prepareForSegue 调用的一部分,您应该为控制器和数据设置类型标识符- 无论数据来自哪里。

    UITableViewController 类中,您可以隐藏/显示此数据类型所需的功能 - 例如搜索栏,并在 tableView 方法中选择您需要的数据源。

    这样,您需要维护的一个 UITableViewController 类比一个专用类稍微复杂一点,但比 7 个或更多类更易于维护!

    假设您已经设置了一个变量 dataType 来识别您需要的数据类型,您可以为 numberOfRowsInSection 设置类似的内容,然后为其他 tableView 方法设置类似的内容

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        switch self.dataType {
        case dataType.MyFirstDataType:
            return myFirstDataTypeArray.count
    
        case dataType.MySecondDataType:
            return mySecondDataTypeArray.count
    
        case dataType.TheCoreDataType:
            return myCoreDataArray.count
    
        default:
            break
        }
    }
    

    【讨论】:

    • 感谢您的评论。我已经更新了问题,数据源和委托是相同的,无论如何都会从父级使用。它主要是我获得的不同项目列表和一些 GUI 更改。因此 viewDidLoad 可能会有所不同,因为必须将搜索栏添加到一个列表中,并且将使用与 APIManager 不同的方法来检索该列表。
    【解决方案2】:

    创建一个包含所有子视图和单元格的父 UITableViewController,包括 searchController。初始化它并根据条件添加/删除视图和单元格

    【讨论】:

      猜你喜欢
      • 2019-07-12
      • 2015-07-30
      • 1970-01-01
      • 2012-01-09
      • 2012-01-21
      • 2016-03-25
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多