Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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
Ios PageViewController-将变量传递给子视图 我所拥有的_Ios_Swift_Uipageviewcontroller - Fatal编程技术网

Ios PageViewController-将变量传递给子视图 我所拥有的

Ios PageViewController-将变量传递给子视图 我所拥有的,ios,swift,uipageviewcontroller,Ios,Swift,Uipageviewcontroller,我有一个ViewController(TutorialViewController)和一个UIPageViewController(TutorialPageViewController)。序列图像板上还有3个附加视图,具有序列图像板ID: 绿色视图控制器 BlueViewController RedViewController 我一直在关注这一点(作者的荣誉,写得很好) 在绿色视图控制器上,我定义了一个变量: var passedVariable = "" 在ViewDidLoad中,我将

我有一个ViewController(TutorialViewController)和一个UIPageViewController(TutorialPageViewController)。序列图像板上还有3个附加视图,具有序列图像板ID:

  • 绿色视图控制器
  • BlueViewController
  • RedViewController
我一直在关注这一点(作者的荣誉,写得很好)

在绿色视图控制器上,我定义了一个变量:

var passedVariable = ""
在ViewDidLoad中,我将其打印出来

以下是具有代码的两个控制器:

UIViewController(教程视图控制器): UIPageViewController 我试过的 我已尝试先声明视图控制器,如下所示:

let vc0 = GreenViewController(nibName: "GreenViewController", bundle: nil)
然后像这样传递数据:

override func viewDidLoad() {
   vc0.passedVariable = "This was passed, Dance with Joy"
}
控制台中没有打印任何内容

我还尝试将上面的包更改为:

bundle: NSBundle.mainBundle()
还是娜达

问题: 我计划从alamofire请求加载TutorialViewController上的数据,我希望将该数据传递到其中一个ViewController(绿色、蓝色、红色)


如何将从TutorialViewController获取的数据传递到将要加载的子视图之一?

首先,我要感谢您查看我的教程以及您对它所说的所有美好的事情

第二,我有一个解决方案给你!我继续,并在教程中链接。我也会在这里发布代码

(1) 创建一个
UIViewController
子类以向其添加自定义属性。对于这个例子,我选择添加一个
UILabel
,因为它在运行应用程序时最容易查看

class ColoredViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

}
(2) 在
Main.storyboard
内部,在Identity Inspector中将每个
UIViewController
“页面”的自定义类更改为
ColoredViewController

(3) 在每个“页面”中添加一个
ui标签
,并根据需要对其进行约束。我选择在容器中垂直和水平居中。不要忘记将
UILabel
链接到
ColoredViewController
@ibvar标签:UILabel

(4) 可选:我以这种方式删除了默认的“标签”文本,如果我们从未在代码中设置标签的文本,我们将不会向用户显示“标签”

(5) 我们需要对
TutorialPageViewController
执行一些TLC,以便它知道
orderedViewControllers
现在是一个
ColoredViewController
数组。为了方便起见,我将粘贴整个类:

class TutorialPageViewController: UIPageViewController {

    weak var tutorialDelegate: TutorialPageViewControllerDelegate?

    private(set) lazy var orderedViewControllers: [ColoredViewController] = {
        // The view controllers will be shown in this order
        return [self.newColoredViewController("Green"),
            self.newColoredViewController("Red"),
            self.newColoredViewController("Blue")]
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        dataSource = self
        delegate = self

        if let initialViewController = orderedViewControllers.first {
            scrollToViewController(initialViewController)
        }

        tutorialDelegate?.tutorialPageViewController(self,
            didUpdatePageCount: orderedViewControllers.count)
    }

    /**
     Scrolls to the next view controller.
     */
    func scrollToNextViewController() {
        if let visibleViewController = viewControllers?.first,
            let nextViewController = pageViewController(self,
                viewControllerAfterViewController: visibleViewController) {
                    scrollToViewController(nextViewController)
        }
    }

    private func newColoredViewController(color: String) -> ColoredViewController {
        return UIStoryboard(name: "Main", bundle: nil) .
            instantiateViewControllerWithIdentifier("\(color)ViewController") as! ColoredViewController
    }

    /**
     Scrolls to the given 'viewController' page.

     - parameter viewController: the view controller to show.
     */
    private func scrollToViewController(viewController: UIViewController) {
        setViewControllers([viewController],
            direction: .Forward,
            animated: true,
            completion: { (finished) -> Void in
                // Setting the view controller programmatically does not fire
                // any delegate methods, so we have to manually notify the
                // 'tutorialDelegate' of the new index.
                self.notifyTutorialDelegateOfNewIndex()
        })
    }

    /**
     Notifies '_tutorialDelegate' that the current page index was updated.
     */
    private func notifyTutorialDelegateOfNewIndex() {
        if let firstViewController = viewControllers?.first as? ColoredViewController,
            let index = orderedViewControllers.indexOf(firstViewController) {
                tutorialDelegate?.tutorialPageViewController(self,
                    didUpdatePageIndex: index)
        }
    }

}

// MARK: UIPageViewControllerDataSource

extension TutorialPageViewController: UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController,
        viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
            guard let coloredViewController = viewController as? ColoredViewController,
                let viewControllerIndex = orderedViewControllers.indexOf(coloredViewController) else {
                return nil
            }

            let previousIndex = viewControllerIndex - 1

            // User is on the first view controller and swiped left to loop to
            // the last view controller.
            guard previousIndex >= 0 else {
                return orderedViewControllers.last
            }

            guard orderedViewControllers.count > previousIndex else {
                return nil
            }

            return orderedViewControllers[previousIndex]
    }

    func pageViewController(pageViewController: UIPageViewController,
        viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
            guard let coloredViewController = viewController as? ColoredViewController,
                let viewControllerIndex = orderedViewControllers.indexOf(coloredViewController) else {
                return nil
            }

            let nextIndex = viewControllerIndex + 1
            let orderedViewControllersCount = orderedViewControllers.count

            // User is on the last view controller and swiped right to loop to
            // the first view controller.
            guard orderedViewControllersCount != nextIndex else {
                return orderedViewControllers.first
            }

            guard orderedViewControllersCount > nextIndex else {
                return nil
            }

            return orderedViewControllers[nextIndex]
    }

}

extension TutorialPageViewController: UIPageViewControllerDelegate {

    func pageViewController(pageViewController: UIPageViewController,
        didFinishAnimating finished: Bool,
        previousViewControllers: [UIViewController],
        transitionCompleted completed: Bool) {
        notifyTutorialDelegateOfNewIndex()
    }

}

protocol TutorialPageViewControllerDelegate: class {

    /**
     Called when the number of pages is updated.

     - parameter tutorialPageViewController: the TutorialPageViewController instance
     - parameter count: the total number of pages.
     */
    func tutorialPageViewController(tutorialPageViewController: TutorialPageViewController,
        didUpdatePageCount count: Int)

    /**
     Called when the current index is updated.

     - parameter tutorialPageViewController: the TutorialPageViewController instance
     - parameter index: the index of the currently visible page.
     */
    func tutorialPageViewController(tutorialPageViewController: TutorialPageViewController,
        didUpdatePageIndex index: Int)

}
(6) 内部
TutorialViewController
:让我们设置
标签.text
。我选择使用
viewDidLoad
,但可以将此逻辑填充到网络请求完成块中

override func viewDidLoad() {
    super.viewDidLoad()

    if let greenColoredViewController = tutorialPageViewController?.orderedViewControllers.first {
        greenColoredViewController.label.text = "Hello world!"
    }
}

希望这有帮助

显然,根据评论,如何解决这一问题仍然存在困惑

我将尝试介绍一种方法,并解释这种方法的意义。但是请注意,还有一些其他可行的方法可以解决这个问题

根视图控制器 首先,我们看一下“根”控制器,它是
TutorialViewController
的一个实例。这个人负责获取一个“模型”。该模型是纯数据的一个实例。定义和初始化页面视图控制器必须合适。因为我们有很多页面,所以这个模型是某种数组或某种对象的列表是有意义的

对于这个例子,我使用一个字符串数组——只是为了说明如何实现它。一个真实的示例将获得一个可能更复杂的对象数组,其中每个对象都将在自己的页面中呈现。可能是通过网络请求从远程资源获取了阵列

在本例中,字符串恰好是页面视图控制器的“颜色”。我们为类
TutorialViewController
创建适当的属性:

class TutorialViewController: UIViewController {

    @IBOutlet weak var pageControl: UIPageControl!
    @IBOutlet weak var containerView: UIView!


    private let model = ["Red", "Green", "Blue"]

    ...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let tutorialPageViewController = segue.destinationViewController as? TutorialPageViewController {
        self.tutorialPageViewController = tutorialPageViewController
        self.tutorialPageViewController!.model = self.model
    }
}
class TutorialPageViewController: UIPageViewController {

    internal var model: [String]?
请注意,该属性具有私有访问权限:除了类本身之外,没有其他人可以随意访问它

将模型从根控制器传递到其嵌入式视图控制器 嵌入式视图控制器是
TutorialPageViewController
的一个实例

根视图控制器通过方法
prepareforsgue
将模型传递给嵌入式视图控制器。嵌入式视图控制器必须具有适合其模型视图的适当属性

注意:模型可能有几个方面或视图。已由根视图控制器初始化的模型可能不适合按原样传递给其显示的任何视图控制器。因此,根视图控制器可以首先过滤、复制、重新排序或变换其模型,以使其适合所呈现的视图控制器

在本例中,我们采用如下模型:

在类中
TutorialViewController

class TutorialViewController: UIViewController {

    @IBOutlet weak var pageControl: UIPageControl!
    @IBOutlet weak var containerView: UIView!


    private let model = ["Red", "Green", "Blue"]

    ...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let tutorialPageViewController = segue.destinationViewController as? TutorialPageViewController {
        self.tutorialPageViewController = tutorialPageViewController
        self.tutorialPageViewController!.model = self.model
    }
}
class TutorialPageViewController: UIPageViewController {

    internal var model: [String]?
请注意,
TutorialViewController
本身有一个属性(此处为
model
),该属性由显示视图控制器设置

这里,模型是一个字符串数组。很明显,数组中的元素数以后应该变成页面视图控制器中的页面数。还应该清楚的是,每个元素都呈现在内容视图控制器的相应页面上。因此,我们可以说数组中的一个元素充当每个页面的“模型”

我们需要在
TutorialPageViewController
中提供属性
model

class TutorialViewController: UIViewController {

    @IBOutlet weak var pageControl: UIPageControl!
    @IBOutlet weak var containerView: UIView!


    private let model = ["Red", "Green", "Blue"]

    ...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let tutorialPageViewController = segue.destinationViewController as? TutorialPageViewController {
        self.tutorialPageViewController = tutorialPageViewController
        self.tutorialPageViewController!.model = self.model
    }
}
class TutorialPageViewController: UIPageViewController {

    internal var model: [String]?
请注意,该访问既可以是公共的,也可以是内部的,因此任何显示视图控制器都可以对其进行设置

将模型从
TutorialViewController
传递到每个内容视图控制器 页面视图控制器(
TutorialViewController
)负责创建内容视图控制器数组,其视图呈现页面

使用惰性属性创建视图控制器阵列的简单方法如下所示:

class TutorialPageViewController: UIPageViewController {

    internal var model: [String]?

    private(set) lazy var orderedViewControllers: [UIViewController] = {
        // The view controllers will be shown in this order
        assert(self.model != nil)
        return self.model!.map {
            self.newColoredViewController($0)
        }
    }()
即时通讯