设计一个健壮的大型文件下载系统

  编译:伯乐在线 - BEASTQ

  如有好文章投稿,请点击 → 这里了解详情

  如需转载,发送「转载」二字查看说明

  摘要

  Kersten Broich 和 Justus Gandhi 只使用了一个 tableview 来展示三种形式的 UI 界面。方法看起来很简单,UI 切换效果也非常漂亮。

  在我们的一次评估会议中,我们面临一个累赘、高代价的挑战,这会让视图控制器变得臃肿。

  面临的挑战是,不使用导航视图控制器栈的前提下,创建一个登录和注册的表格。视图中只有标签、按钮和文本输入框,所有控件都需要添加位移动画。这防止用户丢失已经键入文本框的任何凭证。

  

  入门

  虽然我们已经在考虑创建一个复杂的状态机,使用动态布局来回切换、隐藏显示恰当的视图。我们想到了一个有趣的想法,使用一个 UITableView 并让其动画 API 为我们完成所有工作。UITableView 看深一些,发现他们实际上是相当灵活的。

  我们开始把视图分割成独立的单元,如分隔符、文本框、按钮等,每个单元是一个 UITableViewCell。同样,我们创建一个 Swift Enumeration,声明每个单元格的标识符。

  enumAuthCellType: String{

  caseHeadline

  caseEmailTextField

  caseNameTextField

  casePasswordTextField

  caseLoginButton

  caseSeparator

  }

  然后我们把视图的每个可能状态(例如登录或注册)分解成有单个组成的列表。举个例子,这里是两个状态的简化版本。

  let loginState= [

  .Headline,

  .Separator,

  .EmailTextField,

  .PasswordTextField,

  .LoginButton

  ]

  letregisterState= [

  .EmailTextField,

  .NameTextField,

  .PasswordTextField,

  .LoginButton

  ]

  动画状态切换

  然后我们考虑如何在视图之间来回动画。UITableView 公开了一些简单的 API,用于平缓插入、删除带索引路径数组标识的单元格:

  func insertRowsAtIndexPaths(_indexPaths: [NSIndexPath]withRowAnimationanimation: UITableViewRowAnimation)

  func deleteRowsAtIndexPaths(_indexPaths: [NSIndexPath],withRowAnimationanimation: UITableViewRowAnimation)

  所以,我们必须取出即将添加的单元格的 NSIndexPaths,以及在两个状态间消失的视图的索引。

  假设用户在登录视图上启动,然后发现自己没有账户,并按下按钮注册新账户。

  在这种情况下,必须删除索引 0 和 1 的 .Headline 和 .Separator,并且在索引 1 的位置添加新单元格 .NameTextField。集合更改如下:

  let addedIndexes= [1]

  letremovedIndexes= [0,1]

  改变状态后,必须转换为 NSIndexPaths 数组,并传递到前面提到的 UITableView 方法来触发状态改变动画。

  自动生成集合改变

  自然想到的解决办法是,在视图状态转换间,指定插入和删除行的 NSIndexPaths 数组。但我们寻找一个更加可维护的解决方案,旨在更少的手工工作。

  自动生成这些变更集不是个琐碎问题。解决方案的关键是旨在解决最长公共子序列问题(LCS)的算法。幸运的是,我们在 github 上找到了著名的 SwiftLCS 库(https://github.com/Frugghi/SwiftLCS),它可以帮助你着手识别两个结合的变更集。

  我们最终基于 SwiftLCS 的解决方案如下:

  func transitionToViewState(newState: AuthViewState){

  let diff= currentState.diff(newState)

  tableView?.beginUpdates()

  tableView?.insertRowsAtIndexPaths(diff.addedIndexes,

  withRowAnimation: .Fade)

  tableView?.deleteRowsAtIndexPaths(diff.removedIndexes,

  withRowAnimation: .Fade)

  tableView?.endUpdates()

  }

  该 transitionToViewState 方法可以与 AuthCellType 元素数组调用,表视图会自动动画到对应的状态。

  结论

  这个例子可能不会适合每个人。对我们来说,它更多的是提醒我们,始终重新思考如何使用 UIKit 与现有工具一起使用的可能性。

看完本文有收获?请分享给更多人

关注「 iOS大全 」,提升iOS技能

声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
推荐阅读