ios - 在 API 请求后更新 UIPageViewController 的正确方法

标签 ios swift alamofire uipageviewcontroller

当我尝试使用 Alamofire 执行 GET 请求时遇到问题。在我的 viewDidLoad 方法中。我已经检查过我的请求是否有效并且我的数组已填充但是当我运行代码时我得到一个 fatal error :索引超出范围因为当我调用 getViewControllerAtIndex 方法时数组在那一刻是空的。 如果我想使用来 self 的 API 的数据创建我的 UIPageViewController,我该怎么办。 这是我在 ViewController.swift 中的代码

    import UIKit
import Foundation
import Alamofire


class ViewController: UIPageViewController, UIPageViewControllerDataSource {

    var arrPageTitle = [String]()
    var arrPagePhoto = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let guidesEndpoint: String = "http://testapi.eu-gb.mybluemix.net/guides"

        Alamofire.request(guidesEndpoint).responseJSON { (response) in

            if let JSON = response.result.value {

                //print("JSON: \(JSON)")

                if let guides = JSON as? [String : AnyObject] {

                    if let guideResourceList = guides["_embedded"] as? [String : AnyObject] {

                        //print(guideResourceList)
                        if let guidesArray = guideResourceList["guideResourceList"] as? [AnyObject] {

                            for guide in guidesArray {

                                if let guideGuide = guide["guide"] as? [String : AnyObject] {
                                    if let textItem = guideGuide["text"] as? String {
                                        // Populate arrPageTitle
                                        self.arrPageTitle.append(textItem)
                                        print(textItem)
                                    }

                                }

                                if let guideLinks = guide["_links"] as? [String : AnyObject] {
                                    if let linksObj = guideLinks["imageUrl"] as? [String : String] {
                                        if let link = linksObj["href"] {
                                            // Populate arrPagePhoto
                                            self.arrPagePhoto.append(link)
                                            print(link)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        self.dataSource = self
        self.setViewControllers([getViewControllerAtIndex(0)] as [UIViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
    }

    // Use this method to return to previous view. In this I have put a condition such that if it is first view then return nil otherwise return ViewController.
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        let pageContent: PageContentViewController = viewController as! PageContentViewController
        var index = pageContent.pageIndex
        if index == 0 || index == NSNotFound {
            return nil
        }
        index -= 1

        return getViewControllerAtIndex(index)
    }

    // MARK:- UIPageViewControllerDataSource Methods

    // Use this method to return next view. In this I have put a condition such that if it is last view then return nil otherwise return ViewController.
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

        let pageContent: PageContentViewController = viewController as! PageContentViewController
        var index = pageContent.pageIndex
        if index == NSNotFound { return nil }
        index += 1
        if index == arrPageTitle.count { return nil }

        return getViewControllerAtIndex(index)
    }



    // MARK:- Custom Methods

    func getViewControllerAtIndex(_ index: Int) -> PageContentViewController {

        // Create a new view controller and pass suitable data.
        let pageContentViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageContentViewController") as! PageContentViewController

        // fatal error: Index out of range
        pageContentViewController.strTitle = "\(arrPageTitle[index])"
        pageContentViewController.strPhotoName = "\(arrPagePhoto[index])"
        pageContentViewController.pageIndex = index
        pageContentViewController.numberOfPages = arrPagePhoto.count
        print("\(arrPagePhoto.count)")

        return pageContentViewController

    }

}

这是我的 PageContentViewController.swift

import UIKit

class PageContentViewController: UIViewController {

    @IBOutlet weak var lblTitle: UILabel!
    @IBOutlet weak var imageView: UIImageView!   
    @IBOutlet weak var pageControl: UIPageControl!

    var pageIndex: Int = 0
    var strTitle: String!
    var strPhotoName: String!
    var numberOfPages: Int!

    override func viewDidLoad() {
        super.viewDidLoad()

        imageView.image = UIImage(named: strPhotoName)
        lblTitle.text = strTitle
        pageControl.currentPage = pageIndex
        pageControl.numberOfPages = numberOfPages

    }

}

有什么想法吗???

最佳答案

self.setViewControllers([getViewControllerAtIndex(0)] as [UIViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)

需要在不超出该范围的 alamofire 回调中调用。您从 (arrPageTitle) 填充的数组在您调用 setViewControllerAtIndex 时将为空,并且您正在访问数组中的值,索引给您带来越界错误。

你应该在这个 if-scope 的末尾调用函数

if let guidesArray = guideResourceList["guideResourceList"] as? [AnyObject] {
     //parsing code...
    self.setViewControllers([getViewControllerAtIndex(0)] as [UIViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)

}

或在 for 循环内,具体取决于您要执行的操作。

关于ios - 在 API 请求后更新 UIPageViewController 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39541509/

相关文章:

ios - Alamofire 请求未在 NSOperation 中运行完成 block

swift - 使用 Alamofire 和 SwiftyJson 从函数返回值

ios - Alamofire : Type of expression is ambiguous in . 获取

ios - iOS UIButton 背景边框问题

swift - 为什么速记参数名称 $0 返回所有参数的元组?

ios - 两个类的 Swift 可选继承

ios - swift 3 : -[_SwiftValue mergeType]: unrecognized selector sent to instance

ios - 如何为 UITableViewHeaderFooterView 设置 textAlignment?

ios - 当 key 未翻译时使用默认语言后备

c# - MonoTouch UIButton、UIPickerView 和重写只读 InputView