2015-06-15 22 views
3

我決定放棄我的UIImageView,而使用的UIPageViewController,使用戶可以在同一頁上的圖像之間滑動。斯威夫特IOS不知道如何連接或使用嵌入式UIPageViewController

我現在已經是一個正常的UIViewController,在我加入,我已經嵌入UIPageViewController一個containerView。

因此,UIPageViewController充當viewcontroller的子視圖。

我有一個「詳細信息」頁面,有關X產品的一些信息而不是隻顯示一個圖像我想要的形象是「滑動式」,使用戶可以看到不同的圖像。但是我不希望PageControllerView充當全尺寸視圖,圖像應始終在視圖控制器內始終可見。

而我現在的問題是我卡住了。我不知道如何連接兩個控制器。所以,如果任何人有一個示例應用程序/教程嵌入式segues /子視圖使用swift請分享。

我研究出瞭解決辦法多虧了答案波紋管:

在我的故事板我有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. 
    } 



} 

回答

3

嵌入實際上是一種賽格瑞的,一旦含有控制器被實例化發生,所以要做到這一點是這樣的在包含控制器上實現prepareForSegue,並在該方法中捕獲對您的子控制器的引用。這裏有一個適合我現在正在開發的項目的例子,它可能不會編譯,但應該給你一個如何繼續的想法 - 讓我知道你是否需要更多的信息。

爲了這個工作,你必須給SEGUE財產identifier。假設你正在使用故事板,這只是segue本身的一個屬性(位於連接父級和子級UIViewControllers的箭頭上的小圓形過渡圖標)。

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... 
} 

這裏的另一個另一種答案是進入一些細節和文件,但在Objective-C,而不是斯威夫特提供:iOS Nested View Controllers view inside UIViewController's view?


現在,你有你的UIPageControllerView一個參考,它需要一個回答某些問題以進行顯示的方式:有多少頁面,我們打開了哪些頁面,當用戶滑動到下一頁和上一頁時,顯示哪些頁面。它用一個常見的UIKit/Cocoa成語dataSource(大量的視圖控制器具有這個屬性)做到這一點。

在鏈接到所述樣本代碼,該方法viewDidLoad包含行self.pageViewController.dataSource = self。這是有效的,因爲作者聲明他的ViewController除了擴展UIViewController之外還符合UIPageViewControllerDataSource協議。然後,他實現了所需的方法:

參見:https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIPageViewControllerDataSourceProtocolRef/index.html

(該dataSource不一定是你的ViewController,你可以做一個單獨的類或結構對於簡單的例子,它可能是罰款,但。 )

您面臨的具體挑戰是根據您的應用程序的要求實施這些方法,以便嵌入式UIPageViewController可以根據您設置的dataSource找出要顯示的內容。

假設您希望它顯示僅拍攝圖像和標籤的ProductImageViewController。理論上,您可以爲每個產品創建故事板,但除非您有少量的產品永遠不會更改,否則這不會奏效。更可能的是,所以你想根據你的產品列表在代碼中創建新的實例。

在示例代碼中,作者只是設置了標籤和圖像的靜態數組,然後pageViewController方法只根據當前位置和滑動方向從數組中抓取相應的數組。你想設置一個dataSource,它知道你的產品列表,你大概從CoreData,CloudKit或其他一些Web服務等動態資源獲得。

作爲一個簡單的實驗來熟悉自己,請嘗試修改該演示的變量self.pageTitlesself.pageImages,並查看它是如何改變嵌入式控制器的行爲的。嘗試修改該代碼,以便不使用兩個數組(一個文本和一個圖像文件名稱),而使用包含您定義的結構或類的單個數組,該數組包含標籤文本和文件名。一旦這個工作,改變,以便代替硬編碼標籤/圖像列表,從產品目錄加載它。什麼是工作,你完成了,運送它:)

+0

謝謝你的偉大的解釋!請如果你有時間看看這個:http://www.veasoftware.com/tutorials/2015/4/2/uipageviewcontroller-in-swift-xcode-62-ios-82-tutorial 它幾乎是與我上面描述的相同的行爲。使用不同的控制器,但在同一視圖中顯示最終內容。但在這裏他們不使用segue來完成它。這種技術與你在賽季中提到的技術有什麼不同,他們之間有沒有優點/缺點?提前致謝! –

+0

在segue/instantiateViewControllerWithIdentifier之間 –

+0

使用Interface Builder時,您使用的是對象而不是類。如果使用故事板嵌入,應用程序將在您訪問'viewDidLoad'時爲您實例化控制器。你想要引用**那個特定的**控制器對象。請記住,故事板是一種可選技術,您可以在代碼中執行所有操作,包括創建對象實例。或者你可以像他那樣結合這兩種方法(不知道爲什麼;我沒有看整個演示)。故事板vs代碼是一個巨大的爭論,太大的話題要解決在評論中,雖然:) – Brett