私はこのチュートリアルに従っています: http://swiftiostutorials.com/ios-tutorial-using-uipageviewcontroller-create-content-slider-objective-cswift/ 複数のスライダーを表示するアプリを作成します。
このチュートリアルは機能していますが、この例では、配列に格納されているものに基づいて画像のみを変更します。
画像の代わりにViewControllersをロードするにはどうすればよいですか
4つのViewControllerがあります。
スライド1でViewController1を表示し、スライド2でViewController2をロードしたい...
これが私のメインの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
}
そしてここに私の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)
}
}
私はSwift/iOS開発に不慣れで、実際に開発することを試みています。あなたの答えを事前にありがとう:)
編集:質問を明確にする
UIPageViewControllerの左右のスライドに対応するビューコントローラーの配列があるようにするにはどうすればよいですか?
したがって、ViewController1を左にスワイプすると、UIViewController2が読み込まれ、右にスワイプすると逆になります。
UIPageViewControllerと同じストーリーボードにビューコントローラー1〜4が定義されていて、それらのストーリーボードIDがViewController0、ViewController1などに設定されていると仮定して、ビューコントローラー配列を設定するメソッドを作成し、viewDidLoad()
を呼び出す前にcreatePageViewController()
_ 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)
}
}
_
そしてcreatePageViewController()
を次のように定義します
_ 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)
}
_
次に、メソッドの前後の2つのデリゲートで:
_ 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
}
_
そしてカウント方法では
_ func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return controllers.count
}
_
実際、表示するビューコントローラをcontrollers
に入力して、そのクラスをストーリーボードでPageItemControllerとして設定することができます(インデックスプロパティを持つため)。
または、各ビューコントローラを独自のクラスとして設定し、ランタイムプロパティの取得と設定を使用できます。
_controller.itemIndex
_の代わりにbeforeメソッドとafterメソッドでcontroller.valueForKey("itemIndex") as Int
を使用します
controller.setValue(i, forKey: "itemIndex")
で_controller.itemIndex = i
_の代わりにpopulateControllersArray()
を使用します。
各コントローラクラスがInt
プロパティitemIndex
を持っていることを確認してください。そうしないと、アプリケーションがクラッシュします。
すべてをコードにまとめるには、次のようにします。
_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
}
_
すべてのページにViewControllersをロードします。表示するすべての画像は、独自のViewController内にあります。それは次のように行われます:
private func getItemController(itemIndex: Int) -> PageItemController?
あなたのすべてのページが同じレイアウトを使用している場合、インターフェイスビルダーでこのViewControllerを設計する以外に、ここで行うことは何もありません。ただし、すべてのページで異なるレイアウトを使用し、異なるデータを表示する場合は、最初にそれらのViewControllerをInterface Builderでプロトタイプ化/設計します。
次に、すべてのViewControllerのクラスを作成し、それらをPageItemControllerから拡張します。インデックス変数をPageItemControllerに保持し、残りのロジックをサブクラスに移動するだけです。
import UIKit
class PageItemController: UIViewController {
// MARK: - Variables
var itemIndex: Int = 0
}
たとえば、画像を保持するviewController
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)
}
}
最後に、指定したインデックスの正しいViewControllerを返すようにgetItemController
関数を変更するだけです。ここでは、ViewControllerにデータを渡すか、単に返すだけです。
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
}
これは素晴らしいレポです:
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)
}
上記のEric Ferreiraのコードを機能させました(Xcode 6.4)。ページビューコントローラーを使用して、レルムデータベースのさまざまなデータを表示するラベルが付いた2つの完全に一意のビューコントローラーを表示したいと思いました。
私は2つのストーリーボードを使用するテストプロジェクトで作業しました。それぞれに、IBOutletを含む独自のクラスによって設定された1つのラベルが含まれ、ラベルにテキストを設定します。これにより、私の表示方法が適切にシミュレーションされます。レルムデータベースデータ。各ストーリーボードクラスはPageItemControllerを継承し、「itemIndex」変数を使用できるようにします。次に、PageItemControllerはUIViewControllerを継承し、継承チェーンを完成させます。
これが、完全にユニークなストーリーボードを使用しようとしている人に役立つことを願っています。