滚动时如何在表视图中添加 20 -20 行的循环?
How to make a loop appending 20 -20 rows in a tableview when scrolling?
我有一个表视图,有时我会得到 1000 或 40,有时甚至是 4 个值,但我希望当我得到超过 100 个值时,我想以 10 - 10 滚动显示我的数组。
向上滚动表格视图,向上滚动 10 行后我需要滚动暂停,使用此代码会出错,我的数组在 [Any] 中并且想要像 Facebook 和 instagram 一样滚动
我想先将我的数组分成 10 行,然后再追加下 10 行。
var allUserArray = [Any]()
override func viewDidLoad() {
super.viewDidLoad()
var index = allUserArray.first
while index < limit {
allUserArray.append(index)
index = index + "1"
}
}
extension AdvanceSearchViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allUserArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "advanceSearch") as! AdvanceSearchTableViewCell
let userData = allUserArray[indexPath.row] as! [String: Any]
let dob = userData["dob"] as! String
let age = self.getAgeFromDate(dob: dob)
let photo1 = userData["photo1"] as? String
let height = userData["Height"] as? String ?? "null"
let religion = userData["Religion"] as? String ?? "null"
cell.userNameLabel.text = "HM- \(userData["ProfileID"] as! String)"
cell.userProfessionLabel.text = userData["Profession"] as? String ?? "null"
cell.userAgeLabel.text = "\(age), \(height), \(religion)"
if let profileImage = photo1 {
urlStringOne = "\(USER_IMAGE_BASE_URL)\(profileImage)"
} else {
if (UserDefaults.standard.value(forKey: "gender") as! String == "Female") {
urlStringOne = "\(USER_IMAGE_URL_MALE)"
} else {
urlStringOne = "\(USER_IMAGE_URL_FEMALE)"
}
}
loadImage(urlStringOne, cell)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if self.allUserArray.count != nil {
self.totalEnteries = self.allUserArray.count
print("idealist/\(self.allUserArray.count)")
print("total123/\(self.totalEnteries)")
var entries = allUserArray.count - 1
print("total-00/\(entries)")
If indexPath.row == entries {
print("(----------)")
if allUserArray.count < totalEnteries {
var index = allUserArray.count as! String
self.limit = index + "20"
while index < self.limit {
self.allUserArray.append(index)
index = index + "1"
}
self.perform(#selector(self.loadTable), with: nil, afterDelay: 2.0)
}
}
}
}
@objc func loadTable() {
self.advanceSearchTableView.reloadData()
}
}
创建一个标志变量来检查 table 现在在哪个单元格上 // var showMore : Bool = false
我建议将您的数组转换为更友好的类型,例如 String
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if allUserArray.count > 100 && showMore != true {
return 20
}else if allUserArray.count > 100 && showMore == true {
return allUserArray.count
}else {
return 20
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexpath.row == 20
// append new content if any
// update flag : showMore = true
// reload table
}
我建议您使用 Bond 框架来绑定您的数据。它建立在 RxSwift 之上。因此,在您的情况下,您只需要一个可变可观察数组并将该数组与您的 tableView 绑定。
let userArray = MutableObservableArray(allUserArray)
userArray.bind(to: collectionView, cellType: UserCell.self) { (cell, name) in
cell.titleLabel.text = name
}
从 "willDisplay" 调用函数并更改数组中的值。使用这种方法,您只需要维护一个数组,它会自动显示在您的 tableView 中。
我将使用示例详细说明 tableView
中的 pagination
。你可以通过它然后在你的项目中实现它。
1. 假设您有一个包含大约 500 个元素的字符串数组。
var allUsers = [String](repeating: "User", count: 500)
2. 创建另一个 String array
,它最初包含 allUsers
array
中的前 10 个元素。
var dataSource = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.addElements() //explained next..
}
dataSource array
将充当 tableView
的实际 dataSource
。
3. 让我们维护一个 offset
来跟踪 index
我们需要从中添加接下来的 10 个元素,即
var nextOffset = 0
func addElements() {
let newOffset = nextOffset+10
for i in nextOffset..<newOffset {
dataSource.append(allUsers[i])
}
nextOffset = newOffset
}
addElements()
方法简单地添加从 nextOffset
.
开始的接下来的 10 个元素
4. UITableViewDataSource
方法看起来像,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "\(dataSource[indexPath.row]) : \(indexPath.row)"
return cell
}
5. 现在实现 UITableViewDelegate
方法 - tableView(_:willDisplay:forRowAt:)
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let currentCount = self.dataSource.count
if currentCount < 500 && indexPath.row == (currentCount-1) { //last row
self.addData()
self.setUpLoaderView(toShow: true)
} else {
self.setUpLoaderView(toShow: false)
}
}
在上述方法中,我检查了是否为最后一个 row
显示了 cell
。如果是,那么我们使用 addData()
方法向其添加更多数据,并使用 setUpLoaderView(toShow:)
方法在底部显示 loaderView
。
6.这里是两种方法的定义,
func addData() {
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
self.addElements()
self.tableView.reloadData()
}
}
func setUpLoaderView(toShow: Bool) {
if toShow {
self.tableView.tableFooterView?.isHidden = false
self.tableView.tableFooterView = self.loaderMoreView
} else {
self.tableView.tableFooterView = UIView()
}
}
在 addData()
中,我已根据您的要求添加了 delay
个 10 seconds
。因此 loader
将在 10 seconds
期间可见,然后 tableView
使用新数据更新。
7. loaderMoreView
只是一个 UIActivityIndicatorView
设置为 tableFooterView
,如:
private lazy var loaderMoreView: UIView = {
let loaderView = UIActivityIndicatorView(style: .whiteLarge)
loaderView.color = UIColor.gray
loaderView.startAnimating()
return loaderView
}()
我有一个表视图,有时我会得到 1000 或 40,有时甚至是 4 个值,但我希望当我得到超过 100 个值时,我想以 10 - 10 滚动显示我的数组。
向上滚动表格视图,向上滚动 10 行后我需要滚动暂停,使用此代码会出错,我的数组在 [Any] 中并且想要像 Facebook 和 instagram 一样滚动
我想先将我的数组分成 10 行,然后再追加下 10 行。
var allUserArray = [Any]()
override func viewDidLoad() {
super.viewDidLoad()
var index = allUserArray.first
while index < limit {
allUserArray.append(index)
index = index + "1"
}
}
extension AdvanceSearchViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allUserArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "advanceSearch") as! AdvanceSearchTableViewCell
let userData = allUserArray[indexPath.row] as! [String: Any]
let dob = userData["dob"] as! String
let age = self.getAgeFromDate(dob: dob)
let photo1 = userData["photo1"] as? String
let height = userData["Height"] as? String ?? "null"
let religion = userData["Religion"] as? String ?? "null"
cell.userNameLabel.text = "HM- \(userData["ProfileID"] as! String)"
cell.userProfessionLabel.text = userData["Profession"] as? String ?? "null"
cell.userAgeLabel.text = "\(age), \(height), \(religion)"
if let profileImage = photo1 {
urlStringOne = "\(USER_IMAGE_BASE_URL)\(profileImage)"
} else {
if (UserDefaults.standard.value(forKey: "gender") as! String == "Female") {
urlStringOne = "\(USER_IMAGE_URL_MALE)"
} else {
urlStringOne = "\(USER_IMAGE_URL_FEMALE)"
}
}
loadImage(urlStringOne, cell)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if self.allUserArray.count != nil {
self.totalEnteries = self.allUserArray.count
print("idealist/\(self.allUserArray.count)")
print("total123/\(self.totalEnteries)")
var entries = allUserArray.count - 1
print("total-00/\(entries)")
If indexPath.row == entries {
print("(----------)")
if allUserArray.count < totalEnteries {
var index = allUserArray.count as! String
self.limit = index + "20"
while index < self.limit {
self.allUserArray.append(index)
index = index + "1"
}
self.perform(#selector(self.loadTable), with: nil, afterDelay: 2.0)
}
}
}
}
@objc func loadTable() {
self.advanceSearchTableView.reloadData()
}
}
创建一个标志变量来检查 table 现在在哪个单元格上 // var showMore : Bool = false 我建议将您的数组转换为更友好的类型,例如 String
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if allUserArray.count > 100 && showMore != true {
return 20
}else if allUserArray.count > 100 && showMore == true {
return allUserArray.count
}else {
return 20
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexpath.row == 20
// append new content if any
// update flag : showMore = true
// reload table
}
我建议您使用 Bond 框架来绑定您的数据。它建立在 RxSwift 之上。因此,在您的情况下,您只需要一个可变可观察数组并将该数组与您的 tableView 绑定。
let userArray = MutableObservableArray(allUserArray)
userArray.bind(to: collectionView, cellType: UserCell.self) { (cell, name) in
cell.titleLabel.text = name
}
从 "willDisplay" 调用函数并更改数组中的值。使用这种方法,您只需要维护一个数组,它会自动显示在您的 tableView 中。
我将使用示例详细说明 tableView
中的 pagination
。你可以通过它然后在你的项目中实现它。
1. 假设您有一个包含大约 500 个元素的字符串数组。
var allUsers = [String](repeating: "User", count: 500)
2. 创建另一个 String array
,它最初包含 allUsers
array
中的前 10 个元素。
var dataSource = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.addElements() //explained next..
}
dataSource array
将充当 tableView
的实际 dataSource
。
3. 让我们维护一个 offset
来跟踪 index
我们需要从中添加接下来的 10 个元素,即
var nextOffset = 0
func addElements() {
let newOffset = nextOffset+10
for i in nextOffset..<newOffset {
dataSource.append(allUsers[i])
}
nextOffset = newOffset
}
addElements()
方法简单地添加从 nextOffset
.
4. UITableViewDataSource
方法看起来像,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "\(dataSource[indexPath.row]) : \(indexPath.row)"
return cell
}
5. 现在实现 UITableViewDelegate
方法 - tableView(_:willDisplay:forRowAt:)
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let currentCount = self.dataSource.count
if currentCount < 500 && indexPath.row == (currentCount-1) { //last row
self.addData()
self.setUpLoaderView(toShow: true)
} else {
self.setUpLoaderView(toShow: false)
}
}
在上述方法中,我检查了是否为最后一个 row
显示了 cell
。如果是,那么我们使用 addData()
方法向其添加更多数据,并使用 setUpLoaderView(toShow:)
方法在底部显示 loaderView
。
6.这里是两种方法的定义,
func addData() {
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
self.addElements()
self.tableView.reloadData()
}
}
func setUpLoaderView(toShow: Bool) {
if toShow {
self.tableView.tableFooterView?.isHidden = false
self.tableView.tableFooterView = self.loaderMoreView
} else {
self.tableView.tableFooterView = UIView()
}
}
在 addData()
中,我已根据您的要求添加了 delay
个 10 seconds
。因此 loader
将在 10 seconds
期间可见,然后 tableView
使用新数据更新。
7. loaderMoreView
只是一个 UIActivityIndicatorView
设置为 tableFooterView
,如:
private lazy var loaderMoreView: UIView = {
let loaderView = UIActivityIndicatorView(style: .whiteLarge)
loaderView.color = UIColor.gray
loaderView.startAnimating()
return loaderView
}()