Soru Swift tableView Sayfalandırması
Ben json ayrıştırma kodları ile başarılı çalışma tableview var.Ama yan kaydırma yaparken 1000 öğe daha çok sayfalama gerekebilir. Bunu kodlarımın altında nasıl yapabilirim bilmiyorum. Objektif-c için çok fazla örnek var ama hızlı bir şekilde çalışma örneği bulamadım. Yardımlarını bekliyorum. Bence çok fazla insan olacak. Teşekkür ederim !
import UIKit
class ViewController: UIViewController, UITableViewDataSource,UITableViewDelegate {
let kSuccessTitle = "Congratulations"
let kErrorTitle = "Connection error"
let kNoticeTitle = "Notice"
let kWarningTitle = "Warning"
let kInfoTitle = "Info"
let kSubtitle = "You've just displayed this awesome Pop Up View"
@IBOutlet weak var myTableView: UITableView!
@IBOutlet weak var myActivityIndicator: UIActivityIndicatorView!
var privateList = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
loadItems()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return privateList.count
}
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell:myCell = tableView.dequeueReusableCellWithIdentifier("myCell") as! myCell
cell.titleLabel.text = privateList[indexPath.row]
return cell
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete){
print(indexPath.row)
let alert = SCLAlertView()
alert.addButton("Hayır"){ }
alert.addButton("Evet") {
self.myTableView.beginUpdates()
self.privateList.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Left)
print("Silindi")
self.myTableView.endUpdates()
self.loadItems()
}
alert.showSuccess(kSuccessTitle, subTitle: kSubtitle)
}
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// the cells you would like the actions to appear needs to be editable
return true
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "Detail") {
let destinationView = segue.destinationViewController as! DetailViewController
if let indexPath = myTableView.indexPathForCell(sender as! UITableViewCell) {
destinationView.privateLista = privateList[indexPath.row]
}
}
}
internal func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
{
return 0.0
}
func loadItems()
{
loadItemsNow("privateList")
}
func loadItemsNow(listType:String){
myActivityIndicator.startAnimating()
let listUrlString = "http://bla.com/json2.php?listType=" + listType + "&t=" + NSUUID().UUIDString
let myUrl = NSURL(string: listUrlString);
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "GET";
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print(error!.localizedDescription)
dispatch_async(dispatch_get_main_queue(),{
self.myActivityIndicator.stopAnimating()
})
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray
if let parseJSON = json {
self.privateList = parseJSON as! [String]
}
} catch {
print(error)
}
dispatch_async(dispatch_get_main_queue(),{
self.myActivityIndicator.stopAnimating()
self.myTableView.reloadData()
})
}
task.resume()
}
}
32
2018-02-12 16:26
Menşei
Cevaplar:
Bunun için de sunucu tarafında değişiklik yapmanız gerekir.
Sunucu kabul edecek fromIndex
ve batchSize
içinde API
sorgu param olarak url.
let listUrlString = "http://bla.com/json2.php?listType=" + listType + "&t=" + NSUUID().UUIDString + "&batchSize=" + batchSize + "&fromIndex=" + fromIndex
Sunucu yanıtında, fazladan bir anahtar olacak totalItems
. Bu, alınan veya alınmayan tüm öğeleri tanımlamak için kullanılacaktır. Bir dizi veya öğeler fromIndex
için batchSize
öğe sayısı.
Uygulama tarafında
İlk loadItem()
ile çağrılacak fromIndex = 0
ve batchSize = 20
(örneğin viewDidLoad()
veya viewWillAppear
). fromAll öğeleri kaldır privateList
çağrıdan önce dizi loadItem()
ilk kez
Sunucu ilk 20 öğeden oluşan bir dizi döndürür ve totalItems
sunucudaki toplam öğe sayısı.
İçindeki 20 öğeyi ekle privateList
dizi ve yeniden yükle tableView
İçinde tableView:cellForRowAtIndexPath
Hücrenin son hücre olup olmadığını kontrol edin. Ve kontrol edin totalItems
(form sunucusu) daha büyüktür privateList.count
. Bu, sunucuda yüklenecek daha fazla öğe olduğu anlamına gelir
if indexPath.row == privateList.count - 1 { // last cell
if totalItems > privateList.count { // more items to fetch
loadItem() // increment `fromIndex` by 20 before server call
}
}
Soru: where is refresh ? will be scrolling ?
Sunucu yanıtı alındığında dizide yeni öğeler ekledikten sonra yenileyin. (Aşama 3)
Kaydırma tetiklenecek tableView:cellForRowAtIndexPath
Kullanıcı kaydırdığında her hücre için. Kod, son hücre olup olmadığını kontrol eder ve kalan öğeleri alır. (adım 4)
Örnek proje eklendi:
https://github.com/rishi420/TableViewPaging
38
2018-02-18 07:26
Bunu yapmanın iyi ve verimli yolu kullanmaktır scrollviewDelegate
masaüstünde
Sadece ekle UIScrollViewDelegate
senin içinde viewController
Denetleyici içinde
//For Pagination
var isDataLoading:Bool=false
var pageNo:Int=0
var limit:Int=20
var offset:Int=0 //pageNo*limit
var didEndReached:Bool=false
viewDidLoad(_){
tableview.delegate=self //To enable scrollviewdelegate
}
Bu temsilci tarafından iki yöntemi geçersiz kıl
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("scrollViewWillBeginDragging")
isDataLoading = false
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("scrollViewDidEndDecelerating")
}
//Pagination
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("scrollViewDidEndDragging")
if ((tableView.contentOffset.y + tableView.frame.size.height) >= tableView.contentSize.height)
{
if !isDataLoading{
isDataLoading = true
self.pageNo=self.pageNo+1
self.limit=self.limit+10
self.offset=self.limit * self.pageNo
loadCallLogData(offset: self.offset, limit: self.limit)
}
}
}
7
2017-12-30 11:20
Bu, iOS10'da yeni bir protokolün eklenmesiyle artık biraz daha kolay: UITableViewDataSourcePrefetching
https://developer.apple.com/documentation/uikit/uitableviewdatasourceprefetching
4
2017-12-16 19:19
Masa bölümünüze başka bir bölüm ekleyin, bu bölümün yüklemeyi belirtmek için bir etkinlik göstergesi içeren bir hücre olacak yalnızca 1 satırı olsun.
internal func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 2;
}
internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if section == 0 {
return privateList.count
} else if section == 1 { // this is going to be the last section with just 1 cell which will show the loading indicator
return 1
}
}
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
if section == 0 {
let cell:myCell = tableView.dequeueReusableCellWithIdentifier("myCell") as! myCell
cell.titleLabel.text = privateList[indexPath.row]
return cell
} else if section == 1 {
//create the cell to show loading indicator
...
//here we call loadItems so that there is an indication that something is loading and once loaded we relaod the tableview
self.loadItems()
}
}
2
2018-02-19 10:12
SWIFT 3.0 - 4 ...
Sayfa numarasını API isteğinde gönderiyorsanız, bu, uygulamanızda sayfalandırma işlemini gerçekleştirmenin en ideal yoludur.
1) Başlangıç Değeri 0 olan değişken akım Sayfasını ve herhangi bir listenin başlangıç değeri hatalı olarak yüklenip yüklenmediğini kontrol etmek için bir boole bildirir.
var currentPage : Int = 0
var isLoadingList : Bool = false
2) Bu liste örneğini alan işlevdir:
func getListFromServer(_ pageNumber: Int){
self.isloadingList = false
self.table.reloadData()
}
3) Bu, sayfa sayısını artıran ve API işlevini çağıran işlevdir.
func loadMoreItemsForList(){
currentPage += 1
getListFromServer(currentPage)
}
4) Bu, scrollView scrolls olduğunda çağrılacak yöntemdir
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (((scrollView.contentOffset.y + scrollView.frame.size.height) > scrollView.contentSize.height ) && ! isLoadingList){
self. isLoadingList = true
self. loadMoreItemsForList()
}
}
Not; bool isLoadingList rolü, kaydırma görünümünün tek bir sürüklemede tablo görünümünün altına daha fazla liste almasını engellemektir.
2
2017-12-14 14:08
Bunu yapmanın başka bir yolu: Her seferinde istek gönderirken öğe almak için bir eşik ayarlayabilirsiniz:
İlk defa 20 element aldığınızı söyleyelim. Sonraki 20 öğenin listesini almak için son getirilen kayıt kimliğini veya numarasını kaydedeceksiniz.
let lastFetchedIndex = 20;
Bu kayıtları myArray'ınıza zaten eklediğinizi varsayıyorum. MyArray, tablo Görünümü'nün veri kaynağıdır. Artık myArray, 40 nesne içeriyor. Şimdi TableView'a eklenmesi gereken indexPath satırlarının listesini yapacağım.
var indexPathsArray = [NSIndexPath]()
for index in lastFetchedIndex..<myArray.count{
let indexPath = NSIndexPath(forRow: index, inSection: 0)
indexPathsArray.append(indexPath)
}
İşte masaüstümü güncelliyorum. Veri kaynağınızın myArray öğenizin zaten güncellendiği anlamına geldiğinden emin olun. Böylece satırları düzgün bir şekilde ekleyebilir.
self.tableView.beginUpdates()
tableView!.insertRowsAtIndexPaths(indexPathsArray, withRowAnimation: .Fade)
self.tableView.endUpdates()
1
2018-02-12 17:52
Bir projeye benzer bir şeye ihtiyacım vardı ve çözümüm şunlardı:
1 - bir değişken numberOfObjectsInSubArray (başlangıç değeri 30 veya istediğiniz her şey) oluşturun
2 - "daha fazlasını göster" seçeneğine her dokunduğumda privateList dizinizden bir dizi nesne eklemek için bir alt dizi oluşturun.
let subArray = privateList?.subarrayWithRange(NSMakeRange(0, numberOfObjectsInSubArray))
Ve onu kullan
internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return subArray.count
}
3- Daha fazla nesne göstermeniz gerektiğinde şunları yapın:
func addMoreObjectsOnTableView () {
numberOfObjectsInSubArray += 30
if (numberOfObjectsInSubArray < privateList.count) {
subArray = privateList?.subarrayWithRange(NSMakeRange(0, numberOfObjectsInSubArray))
} else {
subArray = privateList?.subarrayWithRange(NSMakeRange(0, privateList.count))
}
tableView.reloadData()
}
Umut ediyorum bu yardım eder
1
2018-02-18 21:58