Je suis ce tutoriel: http://swiftiostutorials.com/ios-tutorial-using-uipageviewcontroller-create-content-slider-objective-cswift/ pour créer une application affichant plusieurs curseurs.
Même si ce tutoriel fonctionne, cet exemple ne modifie qu'une image en fonction de celles stockées dans un tableau.
Comment puis-je le faire pour charger ViewControllers au lieu d'images
J'ai 4 ViewControllers:
Je voudrais que la diapositive 1 montre ViewController1 et la diapositive 2 pour charger ViewController2, etc.
Voici mon ViewController principal:
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
}
et voici mon 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)
}
}
Je découvre le développement Swift/iOS et j'essaie vraiment de le développer en le développant. Merci d'avance pour vos réponses :)
EDIT: Pour clarifier la question
Comment faire pour qu'il y ait un tableau de contrôleurs de vue correspondant à la diapositive gauche/droite de UIPageViewController?
Ainsi, lorsque je balaie à gauche sur ViewController1 - UIViewController2 est chargé et inversé pour balayer à droite.
En supposant que les contrôleurs de vue 1 à 4 soient définis dans le même storyboard que votre UIPageViewController et que leurs ID de storyboard soient définis comme ViewController0, ViewController1, etc., créez une méthode pour renseigner votre tableau de contrôleurs de vue et appelez-le dans votre viewDidLoad()
avant appelant createPageViewController()
override func viewDidLoad() {
super.viewDidLoad()
populateControllersArray()
createPageViewController()
setupPageControl()
}
Implémentez la méthode comme suit:
var controllers = [PageItemController]()
func populateControllersArray() {
for i in 0...3 {
let controller = storyboard!.instantiateViewControllerWithIdentifier("ViewController\(i)") as PageItemController
controller.itemIndex = i
controllers.append(controller)
}
}
Et définissez votre createPageViewController()
comme suit
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)
}
puis dans vos deux méthodes délégué avant et après:
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
}
Et dans la méthode de comptage
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return controllers.count
}
En fait, vous pouvez remplir controllers
avec tous les contrôleurs de vue que vous souhaitez afficher. Il suffit de définir leur classe en tant que PageItemController dans le storyboard (afin de disposer de la propriété index).
Vous pouvez également définir chaque contrôleur de vue comme étant sa propre classe et utiliser les propriétés d’exécution et d’exécution.
Utilisez controller.valueForKey("itemIndex") as Int
dans les méthodes before et after au lieu de controller.itemIndex
Utilisez controller.setValue(i, forKey: "itemIndex")
au lieu de controller.itemIndex = i
dans populateControllersArray()
.
Assurez-vous simplement que chaque classe de contrôleur possède la propriété Int
, itemIndex
, sinon votre application se bloquera.
Pour tout rassembler dans votre code, procédez comme suit:
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
}
Vous chargez ViewControllers pour chaque page. chaque image que vous montrez se trouve dans son propre ViewController. Cela se fait par:
private func getItemController(itemIndex: Int) -> PageItemController?
si chaque page de la vôtre utilise la même présentation, il ne reste plus rien à faire ici, à part la conception de ce ViewController dans Interface Builder . Si, toutefois, chaque page utilise une présentation différente et affiche des données différentes, vous devez d'abord créer un prototype concevoir ces ViewControllers dans Interface Builder.
vous créeriez alors des classes pour chaque ViewController et les étendriez à partir de PageItemController. Vous ne gardez que la variable d'index dans PageItemController et déplacez le reste de votre logique vers les sous-classes.
import UIKit
class PageItemController: UIViewController {
// MARK: - Variables
var itemIndex: Int = 0
}
par exemple un viewController qui contient une image
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)
}
}
enfin, il vous suffit de modifier votre fonction getItemController
pour renvoyer le ViewController correct pour l'index spécifié. Ici, vous transmettez des données à ViewController ou vous les renvoyez.
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
}
Voici un excellent rapport pour cela:
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)
}
Le code d'Eric Ferreira ci-dessus fonctionne (Xcode 6.4). Je souhaitais utiliser un contrôleur de vue de page pour afficher deux contrôleurs de vue totalement uniques avec des étiquettes affichant différentes données d'une base de données Realm.
Je l’ai fait fonctionner dans un projet de test où j’ai utilisé 2 story-boards, chacun contenant une seule étiquette définie par sa propre classe contenant l’IBOutlet de l’étiquette et le code définissant le texte de l’étiquette. Données de base de données de royaume. Chaque classe de storyboard hérite de PageItemController afin de disposer de la variable "itemIndex". PageItemController hérite à son tour de UIViewController complétant la chaîne d'héritage.
J'espère que cela aidera quelqu'un qui cherche à utiliser des storyboards totalement uniques.