Как перевести данные с одной вкладки на другую вкладку правильно

Storyboard Image

У меня есть контроллер панели вкладок, который является контроллером начального представления, который также имеет PFLoginViewController, который щенят, если пользователь не вошел в систему. Поток входа/регистрации работает нормально.

Две вкладки 1. a UICollectionView, от которого я теперь буду называть IntroVC 2. a UITableView, который я буду называть FeedVC

Когда пользователь нажимает фотографию в IntroVC, запускается Show segue (через prepareForSegue), который показывает третий экран (UIView), который технически не является вкладкой. С этого момента я буду ссылаться на это как SelectVC.

ПРИМЕЧАНИЕ. Все эти экраны также встроены (деблокированы) в контроллер навигации.

SelectVC отображает фотографию, и есть UIButton, который пользователь может нажать, который запускает Show segue и Unwind segue, чтобы вставить изображение в FeedVC. Причина, по которой я создал Unwind segue, состоит в том, что без нее изображение будет вставляться в FeedVC (вторая вкладка), но первая вкладка будет выделена.

Я исправил это с помощью Unwind segue, но я заметил, что у меня проблема, когда после выбора, когда я нажимаю 1-ю вкладку (Intro VC), на панели Nav есть кнопка "Назад", и чем больше раз я использую SelectVC для ввода изображений, тем больше времени я должен нажать Назад в IntroVC. Я очень смущен тем, как это исправить. Очевидно, что я не правильно подключаю поток, и кажется, что IntroVC создается несколько раз?

Я получаю следующее сообщение в консоли, когда я просматриваю segues в Simulator:

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)
        })
    }
}

Я знаю, что это странно структурировано, и если мне не хватает информации, необходимой для полного понимания, пожалуйста, дайте мне знать, и я отредактирую соответствующим образом.

Ответ 1

Перейдите на другую вкладку с данными

Это решение использует разматывание для перехода на новую вкладку и отправки ее данных.

введите описание изображения здесь

  • Зеленый - вкладка 1
  • Синий является потомком Tab 1
  • Желтый - вкладка 2

Цель: перейти от синего к желтому и передать данные одновременно.

Код

Контроллер Blue View (вкладка 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
        }
    }
}

Контроллер Yellow View (вкладка 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
    }
}

Конструктор интерфейсов

Управляйте перетаскиванием с кнопки на значок "Выход" в верхней части исходного контроллера просмотра. Поскольку мы уже добавили код разматывания segue в контроллер View View, он появится как опция. Выберите его.

введите описание изображения здесь

Примечания

  • Благодаря этому ответу для установки меня на правильный трек.
  • Вы также можете установить режим разматывания путем перетаскивания элемента управления с значка "Выход" на значок "Вид контроллера". Затем вы можете вызвать программный вызов segue. Подробнее см. этот ответ.
  • Для контроллера отображения Tab 1 не было специального кода.

Ответ 2

Я думаю, что ваша проблема возникает в этой строке (метод prepareForSegue)

self.navigationController?.popViewControllerAnimated(true)

так как вы пытаетесь вывести контроллер представления из стека перед представлением SelectVC. Это может быть причиной возможной поврежденной навигационной панели (что, если вы используете контроллер корневого представления?). Вместо этого вы можете попробовать следующий метод:

self.navigationController?.popToRootViewControllerAnimated(true)

Ответ 3

Я не уверен, что понимаю причину, по которой вы вызываете self.navigationController?.popViewControllerAnimated(true) внутри prepareForSegue: от IntroVC.swift: таким образом вы "выталкиваете" ViewController из стека даже перед его представлением (это означает, что вы на самом деле пытаетесь поп-интрова из стека, а не SelectVC).

Первое, что я попробую, прокомментирую эту строку в файле prepareForSegue и посмотрим, что произойдет.

Я не могу попробовать прямо сейчас, но я не удивлюсь, если при вызове self.performSegueWithIdentifier("unwindToVenueView", sender: self) в SelectVC.swift автоматически будет запускаться сам по себе, без необходимости называть его вручную. Если это не так, вы можете добавить popViewControllerAnimated (или, возможно, popToRootViewControllerAnimated), чтобы нажать Select: SelectVC.swift.

Сообщите мне, если это сработает!

Хороший день,

@cdf1982