- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是编程新手,在尝试通过将 tableView 和关联 View 的创建移动到单独的类并将委托(delegate)和数据源从 VC 移动到单独的类来精简我的 ViewController 时遇到了一些问题。
我目前的文件和工作的星座如下:
我从另一个类实例化 View
var detailView: DetailView! { return self.view as? DetailView }
一旦我将下载 UI 的第一部分(单独调用效果很好)
我正在转向凌乱且超出我能力的部分
我调用函数 createReposCard()
dispatchGroup.notify(queue: dispatchQueue) {
DispatchQueue.main.async {
// slide animation
UIView.animate(withDuration: 0.75, delay: 0.5, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.0, options: [], animations: {
self.detailView.reposCard.center = CGPoint(x: self.detailView.reposCard.center.x, y: self.detailView.reposCard.center.y-UIScreen.main.bounds.height)
}, completion: nil)
self.detailView.createReposCard(for: self.repos)
self.detailView.detailsTableView.reloadData()
self.activityIndicator.stopAnimating()
self.activityIndicator.removeFromSuperview()
}
}
代码不完整,只能描述问题,具体做了什么一一说明。我正在传递有关选定用户的信息(无关信息)然后我正在引用我的 DetailsViewController,它仍然是例如持有 CoreData 栈
在初始化程序中,我正在实例化 detailsViewController 并将其传递给持有委托(delegate)的类(我将其传递给那里有对 CoreData 的引用)
class DetailView: UIView {
var selectedUser: User?
var detailsViewController: DetailsViewController!
let detailsTableView: UITableView = {
let tableView = UITableView()
tableView.frame = CGRect.zero
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reposCell")
return tableView
}()
init(selectedUser:User, frame: CGRect) {
super.init(frame: frame)
self.selectedUser = selectedUser
detailsViewController = DetailsViewController()
let tableViewDelegates = TableViewDelegates(detailsViewController: detailsViewController)
detailsTableView.delegate = tableViewDelegates
detailsTableView.dataSource = tableViewDelegates
}
最后代码跳转到描述的类中,我被“隐式展开时意外发现 nil...”击倒了
public class TableViewDelegates: NSObject, UITableViewDataSource,UITableViewDelegate {
private let detailsViewController: DetailsViewController
init(detailsViewController: DetailsViewController){
self.detailsViewController = detailsViewController
super.init()
}
public func numberOfSections(in tableView: UITableView) -> Int {
return detailsViewController.fetchedResultsController.sections?.count ?? 1
}
...
其实我也不知道自己的概念好不好,感觉很迷茫,但我的初衷是这样的:
但正如我所见,简单的数据传递正在克服我的能力。
最佳答案
我觉得这个问题可以分为两部分:
我认为我们没有足够的信息来准确回答这个问题,但我的总体方法是这样的:
关于第 2 步有一个特别的观察:您应该检查方法的执行顺序以确保变量被正确初始化。我为什么要强调这一点?因为某些 View (例如 detailView
)有可能像普通的 UIView 一样被初始化,
然后您尝试访问不属于 的元素UIView
对象(例如,表格 View )。换句话说,在尝试访问它们之前检查您是否设置了自定义 View 。
这是一个更有趣的问题,我认为选择更好的方法将帮助您避免遇到类似您遇到的问题。我将把它分成一些主题。这里的所有内容都是我的个人意见,不一定反射(reflect)最佳方法,尤其是因为这里的“最佳”是主观的。
PersistenceManager 类
首先,将 View Controller 的引用传递给另一个类只是为了访问 CoreData 似乎不是一个好的选择。例如,更好的方法是使用 PersistenceManager
类。您可以使用此类的对象来获取和保存数据。您可以传递此对象而不是 View Controller 。
在某些架构中(例如,VIPER), View Controller 直接访问持久性是不正确的,因此传递一个已获取对象的数组会更合适。例如:
class TableViewController {
private let tableView: UITableView!
private var currentlyDisplayedUsers: [Users]?
func displayUsers(_ users: [Users]) {
self.currentlyDisplayedUsers = users
self.tableView.reloadData()
}
}
在上面的示例中,tableView
将显示 currentlyDisplayedUsers
,这将由方法 displayUsers
更新,该方法将被某人调用否则,就像演示者一样。
网络类
其次,我认为你应该有一个网络类来从互联网上下载数据。您将在应用程序逻辑中使用 Network 类的实例。换句话说,你会有类似的东西
// This is in the application logic
// In MVC, the logic is in the Controller, while in VIPER the logic is in the Interactor
class ApplicationLogic {
let networkAPI: Network?
...
func fetchUserData() {
networkAPI?.fetchUsers() { data, error in
// Update the UI based on the response
// Using the previous example, you could call displayUsers here
}
}
}
TableView、TableViewDelegate 和 TableViewDataSource
最后,如何组织这些家伙。 UITableViewDelegate
负责告诉我们表中的事件,而 UITableViewDataSource
负责用数据填充表,这意味着两者都与 TableView 本身密切相关。也就是说,恕我直言,两者都应该在不同的 swift 文件中实现,但作为具有对 TableView 的引用的 View Controller 的扩展。有点像
// TableViewController+UITableViewDelegate.swift
extension TableViewController: UITableViewDelegate {
...
}
// TableViewController+UITableViewDataSource.swift
extension TableViewController: UITableViewDataSource {
...
}
使用这种方法,委托(delegate)和数据源可以访问前面提到的 users
数组。 Here是如何使用 VIPER 实现类似方法的示例。
所以,我希望我能提供有关这些主题的基本概念。如果您想了解更多有关如何构建代码的信息,我建议您研究 iOS 设计模式和架构模式。 iOS 开发中一些著名的架构设计模式是 MVC、MVP、MVVM 和 VIPER。
关于swift - 通过移走 TableView 使 ViewController 更 slim ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57595878/
我是一名优秀的程序员,十分优秀!