如何正确地将数据从一个Tab转换到另一个Tab

时间:2015-04-24 19:05:54

标签: ios uitabbarcontroller segue uistoryboardsegue unwind-segue

Storyboard Image

我有一个标签栏控制器,它是初始视图控制器,如果用户没有登录,它还有一个PFLoginViewController。登录/注册流程正常。

这两个标签是 1. UICollectionView我将从现在开始称之为IntroVC 2. UITableView,我将其称为FeedVC

当用户点击IntroVC中的照片时,会触发显示segue(通过prepareForSegue),显示第3个屏幕(UIView),这在技术上不是标签。从现在开始,我将其称为SelectVC

注意:所有这些屏幕也嵌入(ded)在导航控制器中。

SelectVC会显示一张照片,用户可以按下UIButton,触发Show segue和Unwind segue,将图片推送到FeedVC。我创建Unwind segue的原因是因为没有它,图像会推入FeedVC(第二个标签),但第一个标签仍然会突出显示。

我用Unwind segue解决了这个问题,但是我注意到我遇到了一个问题,在选择之后,当我按下第一个标签(Intro VC)时,导航栏有一个后退按钮,我使用的次数越多SelectVC按钮用于推送图片,我需要在IntroVC按回更多次。我对如何解决这个问题感到非常困惑。很明显,我没有正确地连接流程,似乎IntroVC多次生成?

当我浏览模拟器中的segues时,我在控制台中收到以下消息:

Nested pop animation can result in corrupted navigation bar

Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

任何帮助将不胜感激!

以下相关代码。

IntroVC.swift

@IBAction func unwindToIntroView(segue: UIStoryboardSegue) {
    self.tabBarController!.selectedIndex = 1


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showFeedItem" {
        let selectScreenVC = segue.destinationViewController as! SelectScreenViewController
        let cell = sender as! UICollectionViewCell
        if let indexPath = self.collectionView!.indexPathForCell(cell) {
            self.navigationController?.popViewControllerAnimated(true)
            selectScreenVC.currentVenue = venueItems[indexPath.row]
        }
}

SelectVC.swift

@IBAction func pushSelection(sender: UIButton) {
    var feedItem = FeedItem()
    if let currentItem = currentItem {
        feedItem.nName = currentItem.nName
        feedItem.imageFile = currentItem.lgImg
        feedItem.userName = PFUser.currentUser()!.username!
        feedItem.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in
            self.performSegueWithIdentifier("unwindToVenueView", sender: self)
        })
    }
}

我知道这是奇怪的结构,如果我缺少完全理解所需的信息 - 请告诉我,我会相应地进行编辑。

2 个答案:

答案 0 :(得分:5)

使用数据

查看另一个标签页

此解决方案使用展开segue切换到新选项卡并发送数据。

enter image description here

  • Green is Tab 1
  • 蓝色是Tab 1的后代
  • 黄色是Tab 2

目标:从蓝色变为黄色并同时传递数据。

代码

蓝视图控制器(标签1的后代)

import UIKit
class BlueViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // this is the data that we want to send
        let myData = "Hello from Blue"

        // Get a reference to the destination View Controller
        // and set the data there.
        if let yellowVC = segue.destination as? YellowViewController {
            yellowVC.data = myData
        }
    }
}

黄色视图控制器(标签2)

import UIKit
class YellowViewController: UIViewController {

    var data: String?

    @IBOutlet weak var dataLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        updateUI()
    }

    @IBAction func comingFromBlueUnwindSegue(segue: UIStoryboardSegue) {
        // This may get called before the UI views have been loaded if
        // the user has not navigated to this tab before. So we need to make
        // sure that the label has been initialized. If it hasn't then we
        // will have our chance to call updateUI() in viewDidLoad().
        // We have to call it here too, though, becuase if the user has
        // previously navigated to this tab, then viewDidLoad() won't get
        // called again.
        if dataLabel != nil {
            updateUI()
        }
    }

    func updateUI() {
        // only update the label if the string data was previously set
        guard let myString = data else {return}
        dataLabel.text = myString
    }
}

Interface Builder

控制从按钮拖动到源视图控制器顶部的“退出”图标。由于我们已将展开的segue代码添加到目标View Controller,因此它将显示为一个选项。选择它。

enter image description here

注释

  • 感谢this answer让我走上正轨。
  • 您还可以通过控制从“退出”图标拖动到“视图控制器”图标来设置展开segue。然后你可以通过编程方式调用segue。有关详细信息,请参阅this answer
  • Tab 1视图控制器没有显示特殊代码。

答案 1 :(得分:0)

我认为你的问题来自这一行(prepareForSegue方法)

self.navigationController?.popViewControllerAnimated(true)

因为您在呈现SelectVC之前尝试从堆栈弹出视图控制器。这可能是可能导致导航栏损坏的原因(如果弹出根视图控制器会怎样?)。您可以尝试使用以下方法:

self.navigationController?.popToRootViewControllerAnimated(true)