Swift4 - 分页

Posted

技术标签:

【中文标题】Swift4 - 分页【英文标题】:Swift4 - Pagination 【发布时间】:2018-03-27 12:04:36 【问题描述】:

我是开发 ios 应用程序的新手。还是不太懂。我成功地只能从第一页很好地显示文章,但是当我向上滚动查看更多时,无法显示其他页面的其他文章。如果有人知道如何从我的收藏视图中进行分页,我真的需要帮助。下面是我使用的api的图片。

下面是我从 api 获取数据的代码 -- (Artikel.swift)

import Foundation
import Alamofire
import SwiftyJSON
import os.log

struct Artikel: ServiceCompletionHandler 
    static func getCategories (completionHandler: @escaping ArrayCompletionHandler) 
        let headers: HTTPHeaders = [
            "Accept": "application/json"
        ]
        let parameters: Parameters = [
            "secret_key": Config.api_key
        ]
        Alamofire.request("\(Config.server_address)/article-categories", method: .post, parameters: parameters, headers: headers)
            .responseJSON  (response) -> Void in
                switch response.result 
                case .success:
                    let json = JSON(response.result.value!)
                    if json["data"].exists() 
                        if let data = json["data"]["data"].array 
                            completionHandler(data, nil)
                         else 
                            completionHandler([], nil)
                        
                     else 
                        completionHandler([], nil)
                    
                case .failure(let error):
                    print(error)
                    completionHandler([], "Network error has occured.")
                
        
    
    static func getArticles(_ category_id: Int, completionHandler: @escaping ArrayCompletionHandler) 
        let headers: HTTPHeaders = [
            "Accept": "application/json",
            "secret-key": Config.api_key]

        let value: Int = category_id
        let newcategory = String(describing: value)

//        var nextpages = NewsSectionViewController.url

        let new_api = Config.server_addforarticle + newcategory

        Alamofire.request(new_api, method: .get, headers: headers)
            .responseJSON  (response) -> Void in
                switch response.result 
                case .success:
                    let json = JSON(response.result.value!)
//                    dump(json, name: "testing")
                    if let articles = json["articles"]["data"].array 
                        completionHandler(articles, nil)

                    else
                        completionHandler([], nil)
                    
                case .failure(let error):
                    print(error)
                    completionHandler([], "Network error has occured.")
                
        
    
    

我在这里展示我的文章。但是,是的,我不能进行分页,它只停留在 4-5 篇文章上。我只是不知道如何做我在我的 android 版本中所做的事情。

NewsSectionViewController.swift

import UIKit
import SwiftyJSON
import AlamofireImage

protocol NewsSectionViewControllerDelegate 
    func updateArrowPosition()


class NewsSectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 

    // MARK: - Variables
    var itemIndex: Int = 0
    var category:JSON!
    var stories:[JSON] = []
    var delegate: NewsSectionViewControllerDelegate?

    // MARK: - Views
    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var collectionView: UICollectionView!
    @IBOutlet var loadingIndicator: UIActivityIndicatorView!

    // MARK: - Constraint
    @IBOutlet var titleTopConstraint: NSLayoutConstraint!

    override func viewDidLoad() 
        super.viewDidLoad()

        self.titleLabel.text = category["name"].stringValue.uppercased()

        self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, 114, 0)
        if #available(iOS 11.0, *) 
            if ((UIApplication.shared.keyWindow?.safeAreaInsets.top)! > CGFloat(0.0)) 
                self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, 173, 0)
                self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 173, 0)
            
        

        self.loadingIndicator.startAnimating()
        Artikel.getArticles(category["id"].intValue) 
            (articles, error) in
            self.loadingIndicator.stopAnimating()
            if error == nil 
                self.stories = articles
                self.collectionView.reloadData()
            
        
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    // MARK: - Collection View
    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return self.stories.count - 1
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        var cell: NewsItemCollectionViewCell?

        let item = stories[indexPath.row + 1]

        if indexPath.row == 0 
            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BigCell", for: indexPath) as? NewsItemCollectionViewCell
         else 
            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SmallCell", for: indexPath) as? NewsItemCollectionViewCell
        

        cell!.titleLabel.text = item["title"].stringValue

        if let thumbUrlString = item["banner_url_large"].string 
            if let thumbUrl = URL(string: thumbUrlString) 
                cell?.coverImageView.af_setImage(withURL: thumbUrl)
            
        

        let wpDateFormatter = DateFormatter()
        wpDateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

        let dayDateFormatter = DateFormatter()
        dayDateFormatter.dateStyle = .medium
        dayDateFormatter.doesRelativeDateFormatting = true

        let date = wpDateFormatter.date(from: item["date_publish_web"].stringValue)!
        cell!.timestampLabel.text = dayDateFormatter.string(from: date)

        return cell!

    

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let story = self.stories[indexPath.row + 1]

        let newsContents = self.storyboard?.instantiateViewController(withIdentifier: "NewsContent") as! NewsContentViewController
        newsContents.story = story
        newsContents.title = self.category["name"].string
        self.navigationController?.pushViewController(newsContents, animated: true)
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        if indexPath.row == 0 
            let width = UIScreen.main.bounds.width - 30
            return CGSize(width: width, height: 385 - 20)
         else 
            let width = (UIScreen.main.bounds.width - 45) / 2
            return CGSize(width: width, height: 210)
        

    

    // MARK: - ScrollView
    func scrollViewDidScroll(_ scrollView: UIScrollView) 
        if scrollView == self.collectionView 
            self.titleTopConstraint.constant = 30 - scrollView.contentOffset.y
        
        if let delegate = self.delegate 
            delegate.updateArrowPosition()
        
    


    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
     // Get the new view controller using segue.destinationViewController.
     // Pass the selected object to the new view controller.
     
     */


任何帮助我都非常感谢并提前感谢您:)

【问题讨论】:

谢谢@Kuldeep ...会尝试但是..你知道如何从我的api实现分页吗?请您至少显示我的代码中的提示编辑。对不起,我只是很新:( 【参考方案1】:

在 NewsSectionViewController 中:

1) 添加全局变量:

a) var nextPageUrl: String? ;

b) let numberOfPagination = 5 (5 它是一个 url 页面中的多个项目);

c) 添加变量hasMoreItems

var hasMoreItems: Bool 
    get 
        guard let count = nextPageUrl?.count, count > 0 else 
            return false
        
        return true
    

d) 添加变量numberOfItems

var numberOfItems: Int 
    get 
        return secrets.count
    

2) 将此行 self.stories = articles 更改为 self.stories += articles

3) 添加分页功能:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

    if (indexPath.item + 1 == numberOfItems) && ((indexPath.item + 1) % numberOfPagination == 0) 

        if self.presenter.hasMoreItems 
            self.loadData()
        
    

f) 添加func loadData()

func loadData() 
    Artikel.getArticles(category["id"].intValue, nextPageUrl: nextPageUrl) 
        (articles, error) in
        self.loadingIndicator.stopAnimating()
        if error == nil 
            self.stories = articles
            self.collectionView.reloadData()
        
    

在 Artikel 中:

1) 改变getArticles函数

static func getArticles(_ category_id: Int, nextPageUrl: String?, completionHandler: @escaping ArrayCompletionHandler) 

    //...

    let new_api = nextPageUrl ?? Config.server_addforarticle + newcategory

    //...

2) 在此函数中,您可以在ArrayCompletionHandler 中返回nextPageUrl

【讨论】:

谢谢你的朋友.. 你的指南对像我这样的菜鸟很有帮助.... :) 再次感谢

以上是关于Swift4 - 分页的主要内容,如果未能解决你的问题,请参考以下文章

单页分页问题中的多个角度材料表

梦内容页分页标题提取

一个视图中的 CI 多页分页,

以多页分页打印所有数据

CakePHP 2中带有分页分页类的大小为f数组的问题

当我在基于类的视图中应用过滤器时,如何在 django 中使用分页分页。网址总是不断变化我如何跟踪网址