IOS基础——几种页面跳转方式及传值

一、storyboard文件中viewController的跳转和传值

1.跳转

首先storyboard本身提供了很多便捷的方式帮助我们构建布局文件,直接可以通过“连线”操作就可以实现viewContoller之间的跳转,storyboard可以看作是一个页面集合或者viewController的集合。这样不仅可以减少我们编写的代码量,也方便我们查看页面之间的跳转逻辑,下面我简单地说一下,操作方式:
新建几个viewController,使用按住control和左键(触摸板按下去),拖动,就会出现一条带箭头的线,然后移动到你想要跳转的viewController中,释放它,就是出现几个action选项,一般选show即可
在这里插入图片描述在这里插入图片描述

2.Action Segue区别

Segue分为以下几种类型,其中Push、Modal、Popover和Replace已弃用。

  • Show
  • Show Detail
  • Present Modally
  • Present as Popover
  • Custom
  • Push
  • Modal
  • Popover
  • Replace

Show

  • 该方法为视图控制器提供了自适应、灵活的呈现方式。
  • 用在UINavigationController堆栈视图时。目的地视图会被压入导航栈顶部。导航条提供一个后退按钮。
  • 用在UIViewController实例时,和present()效果一致。

Show Detail

  • 与Show相似,但会替换源视图,没有导航条和后退按钮。

Present Modally

  • 使用方法present()
  • 有多种不同呈现方式,可根据需要设置。在iPhone中,一般以动画的形式自下向上覆盖整个屏幕,用户无法与上一个视图交互,除非关闭当前视图;在iPad中,常见呈现为一个中心框,中心框以动画形式自下向上弹出,同时使底层视图控制器变暗。
  • 不提供返回按钮。

Present as Popover

  • 在iPad中,目标视图以浮动窗样式呈现,点击目标视图以外区域,目标视图消失;在iPhone中,默认目标视图以模态覆盖整个屏幕。

下面GIF演示了Show和Present在新页面出现方式的不同:
在这里插入图片描述

3.反向转场

Present Modally不提供返回按钮,需要定于“反向转场(unwind segue)”

在需要退出的控制器定于一个方法:此方法只有一个参数,类型必须是UIStoryboardSegue,且有修饰符@IBAction

@IBAction func close(segue:UIStoryboardSegue){
	let vc = segue.source as! ReviewViewController
	//反向传值
	print(vc.data)
}

在Storyboard上指定反向转场关联
Ctrl拖到 关闭按钮 至视图的Exit,选择close:
在这里插入图片描述

4.传值

在第一个页面覆写prepare方法,在vc.message中填要传的数据。

扫描二维码关注公众号,回复: 9701021 查看本文章
    //使用SB连接转场每次都会触发下面方法
    override func prepare(segue: UIStoryboardSegue, sender: AnyObject?) {
        //可再每个连线处类似按钮的东西加上identifier,即可判断不同指向
        if segue.identifier == "segueIdentifier" {
 
            //不带导航的方式
             let vc = segue.destinationViewController as! nextVC
            //下个视图前了带了导航的方式
            //let nv_vc = segue.destinationViewController.childViewControllers[0] as! nextVC
            vc.message = "传值"
        }
    }

二、不带任何布局文件的viewController之间的跳转

1.用在UIViewController实例

present()方法与dismiss()方法相对应。

    //present方式
    let vc = SecondViewController()
    self.present(vc, animated: true, completion: nil)
	//dismiss方式
	self.dismiss(animated:true,completion:nil)	

2.用在UINavigationController实例

pushViewController()方法与popViewController()方法相对应。

	let viewController = ViewController()
	self.navigationController?.pushViewController(viewController, animated:true)

返回上一个视图

	self.navigationController?.popViewController(animated:true)
	//使用匿名变量可以消除“返回值未使用”警告
	_ = self.navigationController?.popViewController(animated:true)

返回到指定视图

    //弹回根视图
    self.navigationController?.popToRootViewControllerAnimated(true)
    //指定位置
    self.navigationController?.popToViewController((self.navigationController?.viewControllers[0])!, animated: true)

三、带Storyboard 界面的viewController之间的跳转

    let sb = UIStoryboard(name: "Main", bundle:nil)
    let vc = sb.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
    
    self.presentViewController(vc, animated: true, completion: nil)

注意:记得要设置 StoryboardID ,可以在 Identifier inspector 中修改
在这里插入图片描述

四、传值

正向传值

方式1

在第一个界面添加一个action

@IBAction func touch(_ sender:AnyObject){
	let vc = ViewControllerTwo()
	vc.data = "第一个界面传入的数据"
	self.present(vc, animated:true, completion:nil)
}

在第二界面使用

override func viewDidLoad(){
	super.viewDidLoad()
	print(data)
}

方式2

给第二个界面定义一个新的构造方法

init(data:String){
	self.data = data
	super.init(nibName:nil, bundle:nil)
}

在第一个界面使用新的构造方法对ViewControllerTwo类进行实例化

@IBAction func touch(_ sender:AnyObject){
	let vc = ViewControllerTwo(data:"第一个界面传入的数据")
	self.present(vc, animated:true, completion:nil)
}

反向传值

反向传值比正向传值要复杂一些,在实际开发中通常使用协议或者闭包完成反向传值。

方式1使用协议

在第二个界面创建一个协议

protocol ViewControllerTwoProtocol {
	func setData(data:String)
}

var delegate:ViewControllerTwoProtocol?

当点击返回按钮时,进行值得传递

	func ret(){
		delegate?.sentData(data:"第二个界面返回的值")
		self.dismiss(animated:true, completion:nil)
	}

第一个界面要遵守ViewControllerTwoProtocol协议,并实现协议的传值方法

class ViewController:UIViewController:UIViewController,ViewControllerTwoProtocol{
	@IBAction func touch(_ sender:AnyObject){
		let vc = ViewControllerTwo(data:"第一个界面传入的数据")
		//设置代理
		vc.delegate = self
		self.present(vc, animated:true, completion:nil)
	}

	func sentData(data:String){
		print(data)
	}
}

方式2使用闭包

在第二个界面创建闭包,并传值

	var closure:((String)->Void)?

	func ret(){
		self.closure!("第二个界面返回的值")
		self.dismiss(animated:true, completion:nil)
	}

第一个界面对闭包赋值

	@IBAction func touch(_ sender:AnyObject){
		let vc = ViewControllerTwo(data:"第一个界面传入的数据")
		//设置代理
		vc.closure = {(data:String) in
			print(data)
		}
		self.present(vc, animated:true, completion:nil)
	}
发布了43 篇原创文章 · 获赞 1 · 访问量 1078

猜你喜欢

转载自blog.csdn.net/weixin_42046829/article/details/104752685
今日推荐