Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift ios不确定如何连接或使用嵌入式UIPageViewController_Ios_Swift_Uiviewcontroller_Segue_Uipageviewcontroller - Fatal编程技术网

Swift ios不确定如何连接或使用嵌入式UIPageViewController

Swift ios不确定如何连接或使用嵌入式UIPageViewController,ios,swift,uiviewcontroller,segue,uipageviewcontroller,Ios,Swift,Uiviewcontroller,Segue,Uipageviewcontroller,我决定放弃UIImageView,而是使用UIPageViewController,这样用户就可以在同一页面上的图像之间滑动 我现在拥有的是一个普通的UIViewController,因为我添加了一个containerView,其中嵌入了一个UIPageViewController 因此UIPageViewController充当viewcontroller的子视图 我有一个“详细信息”页面,上面有一些关于产品X的信息。我不想只显示一个图像,而是希望图像可以“切换”,以便用户可以看到不同的图像。

我决定放弃UIImageView,而是使用UIPageViewController,这样用户就可以在同一页面上的图像之间滑动

我现在拥有的是一个普通的UIViewController,因为我添加了一个containerView,其中嵌入了一个UIPageViewController

因此UIPageViewController充当viewcontroller的子视图

我有一个“详细信息”页面,上面有一些关于产品X的信息。我不想只显示一个图像,而是希望图像可以“切换”,以便用户可以看到不同的图像。但是我不希望PageControllerView充当全尺寸视图,图像应该始终在viewcontroller中可见

我现在的问题是我被卡住了。我不知道如何连接这两个控制器。因此,如果任何人有使用swift的嵌入式segues/child view示例应用程序/教程,请分享

多亏了下面的回答,我想出了一个解决方案:

在我的故事板中,我有3个VC。VC1带有嵌入式容器视图,该视图有一个到UIPageControllerView的segue,然后我添加了第三个VC“内容视图控制器”来显示UIPageControllerView的图像

ViewController.swift

import UIKit

class ViewController: UIViewController, UIPageViewControllerDataSource {

    var pageViewController: UIPageViewController!
    var pageTitles: NSArray!
    var pageImages: NSArray!

    override func viewDidLoad()
    {
        super.viewDidLoad()

    }

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

    @IBAction func restartAction(sender: AnyObject)
    {
        var startVC = self.viewControllerAtIndex(0) as ContentViewController
        var viewControllers = NSArray(object: startVC)

        self.pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil)
    }

    func viewControllerAtIndex(index: Int) -> ContentViewController
    {
        if ((self.pageTitles.count == 0) || (index >= self.pageTitles.count)) {
            return ContentViewController()
        }

        var vc: ContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController

        vc.imageFile = self.pageImages[index] as! String
        vc.titleText = self.pageTitles[index] as! String
        vc.pageIndex = index

        return vc


    }


    // MARK: - Page View Controller Data Source

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
    {

        var vc = viewController as! ContentViewController
        var index = vc.pageIndex as Int


        if (index == 0 || index == NSNotFound)
        {
            return nil

        }

        index--
        return self.viewControllerAtIndex(index)

    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {

        var vc = viewController as! ContentViewController
        var index = vc.pageIndex as Int

        if (index == NSNotFound)
        {
            return nil
        }

        index++

        if (index == self.pageTitles.count)
        {
            return nil
        }

        return self.viewControllerAtIndex(index)

    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
    {
        return self.pageTitles.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
    {
        return 0
    }



    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "PageViewControllerFitta" {
            self.pageTitles = NSArray(objects: "Explore", "Today Widget")
            self.pageImages = NSArray(objects: "page1", "page2")

            let toView = segue.destinationViewController as! UIPageViewController
            toView.dataSource = self


            var startVC = self.viewControllerAtIndex(0) as ContentViewController
            var viewControllers = NSArray(object: startVC)

            toView.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil)

            toView.view.frame = CGRectMake(0, 30, self.view.frame.width, self.view.frame.size.height - 60)

            self.addChildViewController(toView)
            self.view.addSubview(toView.view)
            toView.didMoveToParentViewController(self)
        }
    }


}
ContentViewController.Swift

import UIKit

class ContentViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    var pageIndex: Int!
    var imageFile: String!



    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.imageView.image = UIImage(named: self.imageFile)


    }

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



}

嵌入实际上是一种序列,在实例化包含的控制器时立即发生,因此实现这一点的方法是在包含的控制器上实现
prepareforsgue
,并在该方法中捕获对子控制器的引用。这是一个改编自我现在正在进行的一个项目的例子,它可能不会编译,但应该给你一个如何继续的想法,如果你需要更多信息,请告诉我

为了使其正常工作,您必须为segue属性指定一个
标识符
。假设您使用的是故事板,这只是segue本身的一个属性(位于连接父和子UIViewController的箭头上的小圆形过渡图标)

见:

(数据源
不必是您的
ViewController
,您可以创建一个单独的类或结构。不过,对于简单的示例,它可能很好。)

您的具体挑战是根据应用程序的要求实施这些方法,以便嵌入式
UIPageViewController
能够从您设置为其
数据源的任何内容中找出要显示的内容

假设您想让它显示一个
ProductImageViewController
,它只获取一个图像和一个标签。理论上,你可以为每种产品创建故事板,但除非你有一小部分永远不会改变的产品,否则这是行不通的。更可能的是,您希望基于产品列表在代码中创建新实例

在示例代码中,作者只需设置标签和图像的静态数组,
pageViewController
方法只需根据当前位置和滑动方向从数组中获取适当的标签和图像。您希望设置一个数据源,该数据源了解您的产品列表,您可能从一些动态源(如CoreData、CloudKit或其他web服务)获得这些产品列表


作为一个熟悉自己的简单实验,尝试修改演示的变量
self.pageTitles
self.pageImages
,看看这会如何改变嵌入式控制器的行为。请尝试修改该代码,以便使用包含定义的结构或类的单个数组(同时包含标签文本和文件名),而不是使用两个数组,一个是文本,另一个是图像文件名。一旦工作正常,就进行更改,这样就可以从产品目录中加载标签/图像列表,而不是硬编码标签/图像列表。那是什么工作,你完成了,发货:)

谢谢你的精彩解释!如果你有时间,请看看这个:它的行为和我上面描述的差不多。使用不同的控制器,但在同一视图中显示最终内容。但在这里,他们不使用segue来做这件事。这项技术与您提到的segues有什么不同,它们之间有什么优点/缺点吗?提前谢谢!在segue/instanceeviewcontrollerwhiteIdentifier之间使用Interface Builder时,您使用的是对象,而不是类。如果您使用故事板进行嵌入,那么当您进入
viewDidLoad
时,应用程序将为您实例化控制器。您需要对该特定控制器对象的引用。不过,请记住,故事板是一种可选技术,您可以在代码中执行所有操作,包括创建对象实例。或者你可以像他那样将这两种方法结合起来(不知道为什么;我没有看整个演示)。故事板与代码是一个巨大的争论,这个话题太大了,无法在评论中提及,不过:)是的,一旦我开始阅读它,它似乎有点太深了。但我仍然不知道我是否需要制作一个VC/ContentViewController来保存pageviewcontroller的图像?或者是否可以将图像直接放置在pageviewcontroller中?否则,要使其与布局/大小调整一起工作似乎有点困难。如果您有使用嵌入式pagecontrollerview的示例,请分享prepareForSegue方式。谷歌这次似乎让我失望了,所以它会帮助我很多。不过,还是非常感谢你迄今为止的帮助!我学到了很多:)我在对答案的修改中提出了其中一些问题。添加注释,因为我不确定您是否会收到其他通知。
class ViewController: UIViewController { // <-- this is the container

    var myEmbeddedViewController: MyCustomUIViewController?

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        switch segue.identifier {
        case .Some("the-identifier-i-used-for-the-segue"):
            myEmbeddedViewController = segue.destinationViewController as? MyCustomUIViewController
        default:
            break
        }
    }

    // ... other UIViewController stuff...
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int