2015-02-09 9 views
14

Ich befolge dieses Tutorial: http://swiftiostutorials.com/ios-tutorial-using-uipageviewcontroller-create-content-slider-objective-cswift/, um eine App zu erstellen, die mehrere Schieberegler zeigt.Swift: UIPageViewController - Laden Sie separate Ansichten

Obwohl ich dieses Tutorial funktioniert, ändert dieses Beispiel nur ein Bild basierend auf denen, die in einem Array gespeichert sind.

Wie kann ich es bekommen Viewcontrollers statt Bilder

Ich habe 4 Viewcontrollers

zu laden:

  • ViewController1
  • ViewController2
  • ViewController3
  • ViewController4

würde ich Dia man gerne ViewController1 und slide2 zeigen ViewController2 usw. laden ....

Hier ist mein Haupt-Viewcontroller:

import UIKit 

class ViewController: UIViewController, UIPageViewControllerDataSource { 

// MARK: - Variables 
private var pageViewController: UIPageViewController? 

// Initialize it right away here 
private let contentImages = ["nature_pic_1.png", 
          "nature_pic_2.png", 
          "nature_pic_3.png", 
          "nature_pic_4.png"]; 

// MARK: - View Lifecycle 
override func viewDidLoad() { 
    super.viewDidLoad() 
    createPageViewController() 
    setupPageControl() 
} 

private func createPageViewController() { 

    let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as UIPageViewController 
    pageController.dataSource = self 

    if contentImages.count > 0 { 
     let firstController = getItemController(0)! 
     let startingViewControllers: NSArray = [firstController] 
     pageController.setViewControllers(startingViewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil) 
    } 

    pageViewController = pageController 
    addChildViewController(pageViewController!) 
    self.view.addSubview(pageViewController!.view) 
    pageViewController!.didMoveToParentViewController(self) 
} 

private func setupPageControl() { 
    let appearance = UIPageControl.appearance() 
    appearance.pageIndicatorTintColor = UIColor.grayColor() 
    appearance.currentPageIndicatorTintColor = UIColor.whiteColor() 
    appearance.backgroundColor = UIColor.darkGrayColor() 
} 

// MARK: - UIPageViewControllerDataSource 

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

    let itemController = viewController as PageItemController 

    if itemController.itemIndex > 0 { 
     return getItemController(itemController.itemIndex-1) 
    } 

    return nil 
} 

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

    let itemController = viewController as PageItemController 

    if itemController.itemIndex+1 < contentImages.count { 
     return getItemController(itemController.itemIndex+1) 
    } 

    return nil 
} 

private func getItemController(itemIndex: Int) -> PageItemController? { 

    if itemIndex < contentImages.count { 
     let pageItemController = self.storyboard!.instantiateViewControllerWithIdentifier("ItemController") as PageItemController 
     pageItemController.itemIndex = itemIndex 
     pageItemController.imageName = contentImages[itemIndex] 
     return pageItemController 
    } 

    return nil 
} 

// MARK: - Page Indicator 

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

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

und hier ist mein PageItemController:

import UIKit 

class PageItemController: UIViewController { 

// MARK: - Variables 
var itemIndex: Int = 0 
var imageName: String = "" { 

    didSet { 

     if let imageView = contentImageView { 
      imageView.image = UIImage(named: imageName) 
     } 

    } 
} 

@IBOutlet var contentImageView: UIImageView? 

// MARK: - View Lifecycle 
override func viewDidLoad() { 
    super.viewDidLoad() 
    contentImageView!.image = UIImage(named: imageName) 
} 
} 

Ich bin neu in Swift/iOS Development und versuche wirklich, durch die Entwicklung darauf zu kommen. Vielen Dank im Voraus für Ihre Antworten :)

EDIT: Zur Frage klar machen

Wie kann ich es so machen, dass es eine Reihe von View-Controller ist, die auf den Schlitten nach links/rechts neben der UIPageViewController entsprechen ?

Also, wenn ich auf ViewController1 nach links wischen - der UIViewController2 geladen wird und umgekehrt für Swipe nach rechts.

+0

UIPageViewController _does_ Last View-Controller.Sie laden View-Controller. Was ist die Frage? – matt

+0

@matt jeder ViewController, den ich oben angegeben habe, enthält Inhalte wie Formulare/Grafiken/Bilder etc ... Wie lege ich fest, welche basierend auf dem Bildlauf angezeigt werden soll. Im Moment ist es nur ein Durchlaufen einer Reihe von Bildern. – DannieCoderBoi

+0

Ich weiß nicht wie, weil ich nicht weiß was du machen willst. Nur eines ist wichtig: Jedes Mal, wenn "viewControllerBeforeViewController" oder "viewControllerAfterViewController" aufgerufen wird, müssen Sie entscheiden, welcher View Controller geladen werden soll. Entscheide dich also! – matt

Antwort

2

Sie laden ViewControllers für jede Seite. Jedes Bild, das Sie anzeigen, befindet sich in seinem eigenen ViewController. Das geschieht durch:

private func getItemController(itemIndex: Int) -> PageItemController? 

, wenn jede Seite von Ihnen das gleiche Layout verwendet, gibt es nichts mehr übrig hier zu tun, außer diese Viewcontroller im Interface Builder zu entwerfen. Wenn jedoch jede Seite ein anderes Layout verwendet und andere Daten anzeigt, würden Sie diese ViewController zuerst im Interface Builder entwerfen/entwerfen.

Dann würden Sie Klassen für jeden ViewController erstellen und sie von PageItemController erweitern. Sie behalten nur die Indexvariable in PageItemController und verschieben den Rest Ihrer Logik in die Unterklassen.

import UIKit 

class PageItemController: UIViewController { 

    // MARK: - Variables 
    var itemIndex: Int = 0 
} 

zum Beispiel eines Viewcontroller, die ein Bild

import UIKit 

class PageImageViewController: PageItemController { 
    // MARK: - Outlets 
    @IBOutlet var contentImageView: UIImageView? 

    // MARK: - Variables 
    var imageName: String = "" { 
     didSet { 
      if let imageView = contentImageView { 
       imageView.image = UIImage(named: imageName) 
      } 
     } 
    } 

    // MARK: - View Lifecycle 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     contentImageView!.image = UIImage(named: imageName) 
    } 
} 

schließlich einfach ändern Sie Ihre getItemController Funktion hält die richtigen Viewcontroller für den angegebenen Index zurück. Hier übergeben Sie entweder Daten an den ViewController oder Sie geben sie einfach zurück.

private func getItemController(itemIndex: Int) -> UIViewController? { 
    var vc: PageItemController? = nil 

    switch itemIndex { 
    case 0: 
     // show an ImageViewController and pass data if needed 
     vc = self.storyboard!.instantiateViewControllerWithIdentifier("ImageController") as PageImageViewController 

     vc.itemIndex = itemIndex 
     vc.imageName = "any_image_file" 
    case 1: 
     // show any other ViewController and pass data if needed 
     vc = self.storyboard!.instantiateViewControllerWithIdentifier("ANY_OTHERController") as ANY_OTHERController 

     vc.PRESENTABLE_DATA = ANY_PRESENTABLE_DATA_SOURCE 
     vc.itemIndex = itemIndex 
    case 2: 
     // show any other ViewController and pass data if needed 
     vc = self.storyboard!.instantiateViewControllerWithIdentifier("ANY_OTHERController") as ANY_OTHERController 

     vc.PRESENTABLE_DATA = ANY_PRESENTABLE_DATA_SOURCE 
     vc.itemIndex = itemIndex 
    } 

    return vc 
} 
10

Sie Ansicht Controller Unter der Annahme, 1-4 in der gleichen Storyboard als UIPageViewController definiert ist, und Sie haben ihren Storyboard-IDs festgelegt, wie ViewController0, ViewController1 und et cetera, dann ein Verfahren schafft ihren View-Controller-Array füllen und nennen sie es in Ihrem viewDidLoad() vor createPageViewController()

override func viewDidLoad() { 
     super.viewDidLoad() 
     populateControllersArray() 
     createPageViewController() 
     setupPageControl() 
    } 

Implementieren sie die Methode, wie so Aufruf:

var controllers = [PageItemController]() 

    func populateControllersArray() { 
     for i in 0...3 { 
      let controller = storyboard!.instantiateViewControllerWithIdentifier("ViewController\(i)") as PageItemController 
      controller.itemIndex = i 
      controllers.append(controller) 
     } 
    } 

und definieren Sie Ihre createPageViewController() wie die folgenden

private func createPageViewController() { 

     let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as UIPageViewController 
     pageController.dataSource = self 

     if !controllers.isEmpty { 
      pageController.setViewControllers([controllers[0]], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil) 
     } 

     pageViewController = pageController 
     addChildViewController(pageViewController!) 
     self.view.addSubview(pageViewController!.view) 
     pageViewController!.didMoveToParentViewController(self) 
    } 

dann in Ihren zwei Delegierten vor und nach Methoden:

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? { 
     if let controller = viewController as? PageItemController { 
      if controller.itemIndex > 0 { 
       return controllers[controller.itemIndex - 1] 
      } 
     } 
     return nil 
    } 
    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? { 
     if let controller = viewController as? PageItemController { 
      if controller.itemIndex < controllers.count - 1 { 
       return controllers[controller.itemIndex + 1] 
      } 
     } 
     return nil 
    } 

Und in der Zählmethode

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

In der Tat, Sie können controllers mit allen View-Controllern füllen, die Sie anzeigen möchten, legen Sie einfach ihre Clas fest s als PageItemController im Storyboard (um index-Eigenschaft zu haben).

Oder Sie können jeden View-Controller als eigene Klasse festlegen und die Laufzeit-Eigenschaft getting und setting verwenden.

Verwenden controller.valueForKey("itemIndex") as Int in dem vor und nach dem Verfahren anstelle von controller.itemIndex

Verwenden controller.setValue(i, forKey: "itemIndex") anstelle von controller.itemIndex = i in populateControllersArray().

Stellen Sie sicher, dass jede Controller-Klasse die Int Eigenschaft itemIndex hat, oder Ihre Anwendung wird abstürzen.

sie alle zusammen in Ihrem Code zu bringen, gehen Sie wie folgt vor:

import UIKit 

import UIKit 

class ViewController: UIViewController, UIPageViewControllerDataSource { 

    // MARK: - Variables 
    private var pageViewController: UIPageViewController? 

    // MARK: - View Lifecycle 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     populateControllersArray() 
     createPageViewController() 
     setupPageControl() 
    } 

    var controllers = [PageItemController]() 


    func populateControllersArray() { 
     for i in 0...3 { 
      let controller = storyboard!.instantiateViewControllerWithIdentifier("ViewController\(i)") as PageItemController 
      controller.itemIndex = i 
      controllers.append(controller) 
     } 
    } 

    private func createPageViewController() { 

     let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as UIPageViewController 
     pageController.dataSource = self 

     if !controllers.isEmpty { 
      pageController.setViewControllers([controllers[0]], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil) 
     } 

     pageViewController = pageController 
     addChildViewController(pageViewController!) 
     self.view.addSubview(pageViewController!.view) 
     pageViewController!.didMoveToParentViewController(self) 
    } 

    private func setupPageControl() { 
     let appearance = UIPageControl.appearance() 
     appearance.pageIndicatorTintColor = UIColor.grayColor() 
     appearance.currentPageIndicatorTintColor = UIColor.whiteColor() 
     appearance.backgroundColor = UIColor.darkGrayColor() 
    } 

    // MARK: - UIPageViewControllerDataSource 
    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? { 
     if let controller = viewController as? PageItemController { 
      if controller.itemIndex > 0 { 
       return controllers[controller.itemIndex - 1] 
      } 
     } 
     return nil 
    } 
    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? { 
     if let controller = viewController as? PageItemController { 
      if controller.itemIndex < controllers.count - 1 { 
       return controllers[controller.itemIndex + 1] 
      } 
     } 
     return nil 
    } 

    // MARK: - Page Indicator 

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

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

func populateControllersArray() sollte Schleife 0 ... 3 – Tr0yJ

+1

Func ViewControllerBefore UND Func ViewControllerAfter sollte Controller zurück [Controller.itemIndex ...] – Tr0yJ

+0

Dank :) lästige Tippfehler. Fixed –

0

Ich habe oben Eric Ferreira Code (Xcode 6.4) zu arbeiten. Ich wollte einen Page View Controller verwenden, um zwei vollständig eindeutige View-Controller mit Beschriftungen anzuzeigen, die unterschiedliche Daten aus einer Realm-Datenbank anzeigen.

Ich habe es in einem Testprojekt arbeiten, wo ich 2 Storyboards verwendet, jede mit einem einzelnen Label, das von seiner eigenen Klasse mit dem IBOutlet auf das Label und Code gesetzt wird, die Beschriftung der Text - das simuliert den Weg entsprechend Ich zeige meine Realm-Datenbankdaten an. Jede Storyboard-Klasse erbt den PageItemController, sodass die Variable "itemIndex" dafür verfügbar ist. Der PageItemController übernimmt wiederum UIViewController, der die Vererbungskette vervollständigt.

Ich hoffe, das hilft jemandem, der versucht, ganz einzigartige Storyboards zu verwenden.

1

Hier ist ein großes Repo hierfür:

https://github.com/goktugyil/EZSwipeController

private func setupPageViewController() { 
    pageViewController = UIPageViewController(transitionStyle: UIPageViewControllerTransitionStyle.Scroll, navigationOrientation: UIPageViewControllerNavigationOrientation.Horizontal, options: nil) 
    pageViewController.dataSource = self 
    pageViewController.delegate = self 
    pageViewController.setViewControllers([stackPageVC[stackStartLocation]], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil) 
    pageViewController.view.frame = CGRect(x: 0, y: Constants.StatusBarHeight, width: Constants.ScreenWidth, height: Constants.ScreenHeightWithoutStatusBar) 
    pageViewController.view.backgroundColor = UIColor.clearColor() 
    addChildViewController(pageViewController) 
    view.addSubview(pageViewController.view) 
    pageViewController.didMoveToParentViewController(self) 
} 
Verwandte Themen