iOS导航控制器和Segues

时间:2020-02-23 14:45:54  来源:igfitidea点击:

在本教程中,我们将讨论并实现iOS UI导航控制器。
这是另一个常见的UI元素,已用作许多iOS应用程序的基础。

iOS导航控制器

导航控制器还拥有一个UIView类实例。
导航控制器的主要用途是在堆栈(正式称为导航堆栈)中创建并保存视图控制器的层次结构。
换句话说,导航控制器维护用户浏览过的View Controller的历史记录。
导航控制器视图由许多子视图组成,这些子视图的顶部包括一个导航列(其中包含可选的标题,后退按钮和其他列按钮),自定义内容视图和底部的可选工具列。

要设置导航控制器,请在情节提要中选择初始视图控制器,然后转到"编辑器">"嵌入在">"导航控制器"。
故事板如下所示:

我们需要将"视图控制器"添加到情节提要中以使用"导航控制器"。
在此之前,我们将讨论segue,segue是在View Controller之间移动的重要组成部分。

Segues

Segues提供了一种连接两个View Controller/scenes的机制。
segues有很多种。

  • Show/Push:将下一个View Controller推到导航堆栈上,从而允许用户单击后退按钮,以通过导航列左上角的后退按钮返回上一屏幕。

  • 显示详细信息:如果下一个视图控制器内容是主详细信息屏幕(UISplitViewController),则显示在详细信息区域中。
    否则,如果不是主要详细信息类型,则将当前内容替换为新内容。

  • 模态呈现:这将从呈现样式(或者自定义样式)列表中选择一种呈现样式,为屏幕上的下一个过渡设置动画。
    通常,下一个视图从下到上过渡到屏幕。
    在iPad的情况下,它将自己置于屏幕中间,而背景中的先前视图控制器内容将居中。

  • Popover演示文稿:在iPad上,这会在一个较小的框中显示前一个视图控制器上的新View Controller,通常带有一个指向创建该Popover的UI元素的箭头。
    在iPhone上使用时,默认情况下它与"当前模式"序列没有太大区别,但可以配置为更像iPad。

  • 自定义:我们可以为这种类型的segue定义自己的行为。

Segue对象属于类UIStoryboardSegue。

要将数据从一个ViewController传递到另一个ViewController,我们必须重写prepareForSegue函数。
显示/推送类型的segue在子视图控制器的导航列中具有默认的后退按钮。
对于其他类型的segue,我们需要添加一个Unwind Segue方法(有关更多信息,请参见后面的教程)。
通过在父视图控制器中添加带有参数如UIStoryboardSegue的IBAction按钮,可以创建展开选择方法。

在此应用程序中,我们将使用segues从第一个View Controller中添加第二个View Controller。
我们将添加一个UITextField,用户可以其中输入在下一个视图控制器中传递并显示的值。

按住Control键单击并拖动按钮到Second View Controller。
选择推送作为手动搜索。

屏幕看起来应该如下图所示。

注意两个视图控制器之间的标记符号。
不同类型的标记的符号不同。

聚焦segue符号,并将segue标识符命名为" mySegue"。

为Second View控制器添加一个新的Cocoa类文件(它应该是UIViewController的子类。
我们在这里将其命名为SecondScreen.swift
选择Second View Controller并在Identity Inspector中链接类名称,如图所示下图。

项目结构

SecondScreen.swift文件用于第二视图控制器。
" info.plist"文件是属性列表,它提供了另一种用于存储应用程序信息的方法。

代码

ViewController.swift

import UIKit

class ViewController: UIViewController,UITextFieldDelegate {

  @IBOutlet var textToPass: UITextField!
  override func viewDidLoad() {
      super.viewDidLoad()
      //Do any additional setup after loading the view, typically from a nib.
      
      textToPass.delegate=self
  
  }
  
  override func viewWillAppear(animated: Bool) {
       self.navigationItem.title = "First Screen"
  }

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
      
      self.navigationItem.title = nil
      
      if segue.identifier == "mySegue"{
          let s = segue.destinationViewController as! SecondScreen
          s.studentName = self.textToPass.text
      }
  }
  
  func textFieldShouldReturn(textField: UITextField) -> Bool //called when 'return' key pressed.
  {
      textField.resignFirstResponder()
      return true;
  }
  
  override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
      textToPass.resignFirstResponder()
      self.view.endEditing(true)
  }
 
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      //Dispose of any resources that can be recreated.
  }
  
}

在上面的代码中,我们添加了用于处理UITextField方法的UITextFieldDelegate协议。
我们已经处理过UITextField,以便在外部轻按或者按下回车键时可以关闭键盘。
注意,代码与我们为Objective-C编写的代码有所不同。

@IBOutlet var textToPass: UITextField!

!标记表示var值严格为UITextField类型,并且不能为null。

textToPass.delegate=self

上面的语句以编程方式将UITextField的委托分配给视图控制器本身。
类似于Control +将文本字段拖到情节提要中的停靠列中。

prepareForSegue是此类中最重要的方法。
让我们来看看它。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
      
      self.navigationItem.title = nil
      
      if segue.identifier == "mySegue"{
          let s = segue.destinationViewController as! SecondScreen
          s.pass = self.textToPass.text
      }
  }

默认情况下,只有在前一个屏幕没有标题时,下一个屏幕才会显示后退按钮。
否则,下一个屏幕的后文本将替换为该屏幕的标题。
因此,我们将标题分配为null。
segue标识符字符串应与情节提要中声明的字符串相同。

s.studentName = self.textToPass.text

" pass"字符串是SecondScreen.swift的实例变量。
我们在这里所做的就是将SecondScreen.swift类的实例变量分配给用户在此处文本字段中键入的文本。

SecondScreen.swift

import UIKit

class SecondScreen: UIViewController {
  
  var pass:String?
  @IBOutlet var textReceived: UILabel!
  override func viewDidLoad() {
      super.viewDidLoad()
      //Do any additional setup after loading the view, typically from a nib.
      

  
      if let name = pass {
          
          if name.characters.count>0 {
          
          textReceived.text = name
          }
      }
  
  }
  
}

仅当用户键入UITextField小部件时,此类才在屏幕上的UILabel中显示" pass"字符串,否则它将显示默认标签字符串。