遵循MVC范式,我应该如何在一个单元格中有效地显示UIViews



我有一个UITableViewCell子类,它在每个单元格中都有一个大的缩略图和一个标题。该单元格可以显示视频、图像、照片库或绘图。

根据单元格显示的内容类型,缩略图顶部会有一个小图标,以明确单元格中显示的内容种类。例如,如果单元格正在显示视频,它会有一个缩略图,上面可能有三角形播放图标,以显示这是一个视频。一幅画可能有一支铅笔。

我想以一种有组织的、遵循MVC的方式来做这件事,因为我正在努力学习如何保持代码的组织性和可维护性。

我的第一个想法是为每种内容类型都有一个UITableViewCell子类,但当唯一改变的是顶部的一个小图标时,似乎需要维护很多不同的类。

我的下一个想法是在类上有一个type实例变量来表示它所显示的内容,然后显示与类型对应的图标。但在这种情况下,单元格不是MVC中的view(V)吗?视图是否也应该在显示它时处理逻辑

还有更好的东西吗?

最后,这是如何与Interface Builder结合使用的?如果是后一种解决方案,我是否将它们全部添加到IB中作为隐藏,然后根据类型以编程方式取消隐藏?

您的视图应该只显示内容,尽可能减少决策。最好的解决方案是为每种类型创建单独的单元格。这是一个非常坚固的体系结构,它将是esker进行更改并添加新功能。

  1. 为每个项目创建单独的模型(照片、视频、图纸)
  2. 创建一个MediaItemCell,它将是每个itemCells(照片、viode等)的基类
    添加每个MediaItem应该具有的基本功能
  3. 为每种类型创建一个单独的单元格。(PhotoCell、VideoCell、DrawingCell)实现特定类型的功能
  4. 在StoryBoard或Xib文件中创建4个不同的单元格,并设置正确的布局和单元格ID

为了获得最佳性能,您应该重用UItableViewCell,避免更改其布局和修改单元格子视图(不要添加或删除子视图)。这就是为什么有一个显示所有对象的单元格是个坏主意。

您的viewController将有一组需要显示的项目。项目数组
[图像,视频,绘图,图像,…]
最好创建一个单独的类来容纳这些项和处理这些项的方法。通过这种方式,您可以隐藏实现细节
我称之为MediaItemsViewModel——它将保存它注意显示的所有项,数组的简单包装器
您可以在objc.io 上阅读更多Clean表视图代码

在CellForRowAtIndexPath中,您将获得一个Object,并根据其类型为其返回相应的单元格

这是Swift的代码。你可以在Objective-C中做类似的事情,也可以在Objective-C 中对对象类型进行动态调度

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  enum Cells: String {
    case Photo = "Photo"
    case Video = "Video"
    case Drawing  = "Drawing"
  }
  let object = objects[indexPath.row]
  switch object {
  case let image as Image:
    let cell = tableView.dequeueReusableCellWithIdentifier("ImgeCellID", forIndexPath: indexPath) as ImageCell
    cell.image = image
  case let image as Video:
    let cell = tableView.dequeueReusableCellWithIdentifier("VideoCellID", forIndexPath: indexPath) as VIdeoCell
    cell.video = video
  return cell
}

Objective-C代码。与Swift中以前的代码非常相似。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  NSDictionary *objectCells = @{@"Video": @"VideoCell",
                                @"Image": @"ImageCell",
                                @"Drawing": @"DrawingCell"};
  id<MediaItem>object = objects[indexPath.row];
  NSString *cellID = objectCells[object.type];
  MediaItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
  // MediaItemTableViewCell class that takes MediaItem
  // Every class has it's own implementation to correctly show media item
  cell.object = object

  return cell;
}

相关内容

最新更新