使用 present modally 将数据从一个 uiviewcontroller 发送到另一个 navigationcontroller

Sending data from one uiviewcontroller to another navigationcontroller using present modally

我是 swift 的新手,我正在使用故事板并使用导航控制器从一个 viewcontroller 连接到另一个。我想将单击的图像的名称发送到下一个 viewcontroller,它从 imageView 在故事板中模态连接。我搜索了很多关于将数据从一个 viewcontroller 传输到另一个 viewcontroller 与导航控制器模态连接但没有可用的解决方案。请让我知道是否需要任何代码,因为我不知道如何继续使用它。我知道这可能是最愚蠢的问题,但在网上搜索了很多之后才发布这个问题。

根据@uraimo 回复进行编辑。

我是否需要为我在故事板上创建的每个转场提供名称?。 我在 viewcontrollerA 上有 2 个固定图像,我在每个图像上放置了一个具有透明背景且没有文本的 uibutton,然后按住 ctrl 拖动到 viewcontrollerB 的导航控制器以进行 模态呈现 并展开后退按钮,即 UIBarButtonItem 到 viewcontrollerA 通过 ctrl 拖动 viewcontrollerB 的后退按钮以退出 viewcontrollerB 并展开它。

这就是我创建导航的方式,从 viewcontrollerA 的 3 张图像中的任意图像单击到 viewcontrollerB,然后单击后退按钮返回到 viewcontrollerA viewcontroller乙。 如果我做错了什么请告诉我,您的 prepareForSegue 代码对完成我的任务是否有用。

基本上,无论是使用 IB 还是以编程方式执行,都必须在执行 segue(或通过代码呈现控制器)之前使用所需的所有数据配置新的 viewcontroller。

在你的情况下,只需设置图像名称(你的自定义视图控制器 class YourViewController 应该有一个特定的字符串 属性 来保存这个值)在当前视图控制器中覆盖 prepareForSegue class:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "yourModalSegueIdentifier" {
            let imgName= (sender as! UIImageView)
            let destination = segue.destinationViewController as UINavigationController
            let yourController = destination.topViewController as YourViewController
            yourController.imageName= <name here>
        }
}

这解决了传递数据的问题。

但是在你的情况下,你需要被点击图像的名称,并且只能通过 UIGestureRecognizer 添加点击事件到 UIImageView 来获得。

因此,您需要一个手势识别,点击后将执行您创建的转场。而且,您将无法获得图像资产的名称(您使用 imageNamed: 创建 UIImage 的名称),因为它不再可用,您将不得不使用accessibilityIdentifier.

这让一切变得更加复杂,似乎大部分都可以通过图形方式完成here and here(但不太清楚如何去做),但通常是通过代码完成。

使用全局变量稍微简化一下:

var currentImage = ""

func viewDidLoad(){
    ...
    ...
    let aTap = UITapGestureRecognizer(target: self, action: Selector("imageTapped:"))
    aTap.numberOfTapsRequired = 1

    //For every image, configure it with recognizer and accessibilityId:
    firstImage.userInteractionEnabled = true
    firstImage.addGestureRecognizer(aTap)
    firstImage.accessibilityIdentifier = "firsImage"
    ...
}

func imageTapped(recognizer:UITapGestureRecognizer) {
    let imageView = recognizer.view as! UIImageView
    currentImage = imageView.accessibilityIdentifier
    self.performSegueWithIdentifier("yourModalSegueIdentifier", sender: self)
}

并更改此:

yourController.imageName= <name here>

对此:

yourController.imageName= currentImage

更新:

  • 我是否需要为我在故事板上创建的每个转场提供名称?

是的,这是识别它们的唯一方法,每个 UIStoryboardSegue 都有一个标识符。但是请记住,segues 并不是从一个控制器转到另一个控制器的唯一方法,如果您完全以编程方式进行(没有 segues),您通常会调用 "presentViewController"。 Segues是一个故事板概念。

同样,关于 segue name/identifier,您直到现在才需要它,因为您从未从代码中引用过该 segue,prepareForSegue 和 performSegueWithIdentifier 都需要它。只需 select segue 并在右侧检查器窗格中为其命名。

你描述的结构似乎没问题,唯一的问题是我不太确定是否真的需要 UIButtons,尝试从 imageview 或直接从 viewcontroller 到目的地的模式转场视图控制器。

更新二:

如果您刚开始,需要一门免费课程来教您基础知识,并让您构建一些有趣的 ios 应用程序,我推荐 hackingwithswift

看看我是怎么做到的

// In a storyboard-based application, you will often want to do a little preparation before navigation
  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

      super.prepare(for: segue, sender: sender)

      switch(segue.identifier ?? "") {

      case "AddItem":
          let destination = segue.destination as? UINavigationController
          guard let itemViewController = destination?.topViewController as? ItemViewController else {
              fatalError("Unexpected destination: \(segue.destination)")
          }
          itemViewController.collection = collection

      case "EditCollection":
          guard let collectionViewController = segue.destination as? EditCollectionViewController else {
              fatalError("Unexpected destination: \(segue.destination)")
          }
          collectionViewController.collection = collection

      default:
          fatalError("Unexpected Segue Identifier; \(segue.identifier)")
      }
  }