cri*_*ald 8 xcode uitableview ios uirefreshcontrol swift
我使用了带有大标题的 UITableView.refreshControl。我试图模仿本机邮件应用程序使用拉动刷新的方式。对我来说,刷新控件会移动并且不会像邮件应用程序那样停留在屏幕顶部。这是一个游乐场:
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
public init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private lazy var refresh: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.backgroundColor = .clear
refreshControl.tintColor = .black
refreshControl.addTarget(self, action: #selector(refreshIt), for: .valueChanged)
return refreshControl
}()
private lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.refreshControl = refresh
tableView.delegate = self
tableView.dataSource = self
return tableView
}()
private var data: [Int] = [1,2,3,4,5]
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// Add tableview
addTableView()
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.title = "View Controller"
}
private func addTableView() {
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
tableView.rightAnchor.constraint(equalTo: view.rightAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
@objc func refreshIt(_ sender: Any) {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.refresh.endRefreshing()
self.data = [6,7,8,9,10]
self.tableView.reloadData()
}
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "Row \(data[indexPath.row])"
return cell
}
}
let vc = ViewController()
let nav = UINavigationController(rootViewController: vc)
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = nav
Run Code Online (Sandbox Code Playgroud)
我怎样才能让微调器粘在顶部,并让它像邮件应用程序一样运行?此外,导航标题会做这件奇怪的事情,它比表格数据向后移动的速度慢,并导致发生一些重叠......感谢任何帮助!
编辑 2020 年 6 月 7 日
我转而使用可修复重叠动画的 diffable 数据源,但是,当触觉反馈发生并导致微调器向上和向下射击时,仍然存在这种奇怪的故障,所以我原来的问题仍然存在 - 怎么做我们让微调器像邮件应用程序一样保持固定在顶部。感谢您查看这个独特的问题 :)!!!
我真的不知道如何回答第一个问题,但既然你问了两个问题,我会继续尝试同时帮助你解决第二个问题。
行到达顶部太快的问题是由于使用了tableView.reloadData(). 这总是在没有动画的情况下完成的,所以发生的事情是可以预料的。
您可以做的是在表视图上使用其他方法,例如插入或删除行,如下所示:
@objc func refreshIt(_ sender: Any) {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.refresh.endRefreshing()
let newData = [6,7,8,9,10]
let newIndexPaths = newData.enumerated().map{IndexPath(row: self.data.count+$0.offset, section: 0)}
self.data.append(contentsOf: newData)
self.tableView.insertRows(at: newIndexPaths, with: .automatic)
}
}
Run Code Online (Sandbox Code Playgroud)
这样,行将添加动画,并且向下滚动动画不会被任何reloadData().
如果您不仅要添加(或删除)行,并且可能必须对两者进行某种组合,那么您可以使用performBatchUpdates 方法在同一动画块中执行添加和删除操作。(iOS 11+)
当然,只有当您能够计算要添加和删除的项目的索引时,这才可行。请记住,添加和删除的行数应始终反映在数据结构中的实际更改中,否则表视图将抛出令人讨厌的异常。
无论如何,这应该总是可行的,但如果你想要开箱即用,你可以使用 iOS 13 diffable 数据源,或者,如果你想要在 iOS 13 之前使用它,你可以使用 instagram 的IGListKit。
两者几乎都使用相同的概念来比较输入数组并自动检测删除和插入。因此,更改数组将自动反映在 tableView 行中的动画更改中。当然,它们都是实现 tableView 的非常不同的方式,因此您实际上不能只更改一小段代码来使其工作。
希望这能有所帮助。
| 归档时间: |
|
| 查看次数: |
975 次 |
| 最近记录: |