swift 子页面传值

2018-04-11 17:51:46 howlaa 阅读数 328

原文地址:https://blog.csdn.net/iotjin/article/details/49681595

第一个界面 A  ,第二个界面B ,从 B 传值 给A


B界面.h

#import <UIKit/UIKit.h>


//第一步 写协议

@protocol passValueDelegate <NSObject>


- (void)passValue:(NSString *)stringValues;


@end



@interface B : UIViewController


@property (weaknonatomicIBOutlet UITextField *value2TextField;


//第二步,声明协议的delegate 属性  代理通常用assingn

@property(nonatomic,assign)id<passValueDelegate>delegate;


@end





 /** ---------------------------------------------------------------------------*/

  B 界面的 .m


  //成功跳转上一界面


        

       [_delegate passValue:self.valueTextField.text];// 代理执行方法必须写在pop之前

            

         NSLog(@" valueTextField %@ ",self.valueTextField.text);

            

        [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1animated:YES];

  // [self.navigationController  popToRootViewControllerAnimated:YES];

 /** ---------------------------------------------------------------------------*/

//     刷新cell的      A *a= [[A alloc]init];

//            a.tableView.delegate=self;

//            [a.tableView reloadData];










 /** ---------------------------------------------------------------------------*/


A.m



#import "B.h"


@interface A () <passValueDelegate>

{


//接收从第2个界面返回的数据

    NSString* _value;


}

@property(nonatomic,strong)B *b;


@end


- (void)viewDidLoad {

    [super viewDidLoad];

    


    

    //    //为了接收从子界面返回的数据

    _b = [[b alloc]init];

        _b.delegate =self;

    

 //   [self.tableView reloadData];

    

    

}




#pragma mark - 从第二个界面返回的数据

- (void)passValue:(NSString *)stringValues

{

    

    [self.tableView reloadData];

    _value = stringValues;

    

    NSLog(@" value %@ ",_value);



}



2015-12-07 13:07:23 zhoushuangjian511 阅读数 5954

Swift 的界面之间的传值,详细介绍3种传值方式》正向传值、协议传值、闭包

  

1、 控制器界面间的正向传值

  

/*

   Swift 的界面之间的传值,详细介绍3种传值方式》

    正向传值、协议传值、闭包

*/

/*

    随着移动的开发,界面之间的传值,也频繁出现,更关键的是在面试的时候也时常被提起。提起最多的是 Block 同时还有协议 (在Swift中是叫 闭包)。我们要详细介绍它。

*/

//  Created by 周双建 on 15/12/7.

//  Copyright © 2015 周双建. All rights reserved.

//


import UIKit


class ViewController: UIViewController {

    let  Screen = CGSizeMake(

        200, 40)

    override func viewDidLoad() {

        super.viewDidLoad()

        // 我们首先,进行正面解说

        //我们先给我们的本控制器设置一个标题 (必须实现导航控制器否者不显示)

        self.title = "第一个控制器"

        self.view.backgroundColor = UIColor.whiteColor()

        // 设置一个点击按钮,驱动事件跳转到下一个控制器

        let  Btn = UIButton(type: UIButtonType.Custom) as UIButton

        Btn.frame = CGRectMake(20, 100, Screen.width, Screen.height)

        Btn.setTitle("跳转到第二个控制器", forState: UIControlState.Normal)

        Btn.setTitleColor(UIColor.magentaColor(), forState: UIControlState.Normal)

        Btn.addTarget(self, action: "BtnClick", forControlEvents: UIControlEvents.TouchUpInside)

        self.view.addSubview(Btn)

        // Do any additional setup after loading the view, typically from a nib.

    }

/*****************************************************************/

    // 按钮点击后,事件的触发

    func BtnClick(){

        //现获取,跳转的控制器对象

        let TVC = TwoViewController()

        //传入一个字符串,给第二个控制器

        TVC.TSTR = "第二个控制器"

        //在传入一个颜色对象

        TVC.TColoer = UIColor.blueColor()

        //实现界面的跳转

        self.navigationController?.pushViewController(TVC, animated: true)

        

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

}


第二个控制器的内容是:

//

//  TwoViewController.swift

//  Swift_009

//

//  Created by 周双建 on 15/12/7.

//  Copyright © 2015 周双建. All rights reserved.

//


import UIKit


class TwoViewController: UIViewController {

    //首先,我们要创建两个对象,来接受上一个界面传来的值

    var  TSTR :String? // 创建一个字符串对象

    var  TColoer :UIColor? //创建一个UIColoer 的颜色对象

    

    override func viewDidLoad() {

        super.viewDidLoad()

        //设置控制器的标题

        self.title = self.TSTR

    // 设置背景颜色

        self.view.backgroundColor = self.TColoer

        // Do any additional setup after loading the view.

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

}


2、 协议的反向传值

//

//  FViewController.swift

//  Swift_009

//

//  Created by 周双建 on 15/12/7.

//  Copyright © 2015 周双建. All rights reserved.

//


import UIKit

/*

   注意了:如果不实现,你的定义的协议方法,会一直报错 。如下:Type 'FViewController' does not conform to protocol 'FTvCdelegte'

   解决方法就是:实现你定义的协议方法

*/

class FViewController: UIViewController,FTVCdelegte{


    override func viewDidLoad() {

        super.viewDidLoad()

        //我们要创建一个返回按钮

        let  Fbtn = UIButton(type: UIButtonType.Custom) as UIButton

        Fbtn.frame = CGRectMake(30, 100, self.view.frame.size.width-60, 40)

        Fbtn.setTitle("跳转到第二个界面", forState: UIControlState.Normal)

        Fbtn.addTarget(self, action: "Click", forControlEvents: UIControlEvents.TouchUpInside)

        Fbtn.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)

        self.view.addSubview(Fbtn)


        // Do any additional setup after loading the view.

    }

/****************************************************************/

    //跳转触发事件

    func Click(){

         let Tvc = FtwoViewController()

        Tvc.delegate_zsj = self

        self.navigationController?.pushViewController(Tvc, animated: true)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

/*****************************************************************/

    //实现协议的方法

    //更改主题名字

    func change(title: String) {

        self.title = title

    }

    //更改背景色

    func ChangeColoer(Coloer: UIColor) {

        self.view.backgroundColor = Coloer

    }

    //是否成功

    func ChangSucces(YON: Bool) {

        print(YON)

    }

    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}


第二个控制器的内容是:

//

//  FtwoViewController.swift

//  Swift_009

//

//  Created by 周双建 on 15/12/7.

//  Copyright © 2015 周双建. All rights reserved.

//


import UIKit

//要创建一个协议

protocol FTVCdelegte : NSObjectProtocol{

    //在协议里面,声明许多方法

    // 第一个,改变标题

    func change(title:String)

    //第二个,改变背景色

    func ChangeColoer (Coloer:UIColor)

    //是否成功的标志

    func ChangSucces(YON:Bool)

}

class FtwoViewController: UIViewController {

    // 创建一个准守协议的对象

    var delegate_zsj :FTVCdelegte?

    override func viewDidLoad() {

        super.viewDidLoad()

        //我们要创建一个返回按钮

        let  Fbtn = UIButton(type: UIButtonType.Custom) as UIButton

        Fbtn.frame = CGRectMake(30, 100, self.view.frame.size.width-60, 40)

        Fbtn.setTitle("返回上一个界面", forState: UIControlState.Normal)

        Fbtn.addTarget(self, action: "Click", forControlEvents: UIControlEvents.TouchUpInside)

        Fbtn.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)

        self.view.addSubview(Fbtn)

        // Do any additional setup after loading the view.

    }

/************************************************************/

    //返回,事件的触发

    func Click(){

        delegate_zsj?.change("首页")

        delegate_zsj?.ChangeColoer(UIColor.redColor())

        delegate_zsj?.ChangSucces(true)

        self.navigationController?.popToRootViewControllerAnimated(true)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}


3、闭包(Block)反向传值

//

//  BBViewController.swift

//  Swift_009

//

//  Created by 周双建 on 15/12/7.

//  Copyright © 2015 周双建. All rights reserved.

//


import UIKit


class BBViewController: UIViewController {


    override func viewDidLoad() {

        super.viewDidLoad()

       //创建一个按钮

        let  btn = UIButton(type: UIButtonType.Custom) as UIButton

        btn.frame = CGRectMake(30, 100, self.view.frame.size.width-60, 40)

        btn.setTitle("跳转到第二个控制器", forState: UIControlState.Normal)

        btn.setTitleColor(UIColor.magentaColor(), forState: UIControlState.Normal)

        btn.addTarget(self, action: "Click", forControlEvents: UIControlEvents.TouchUpInside)

        self.view.addSubview(btn)

        // Do any additional setup after loading the view.

    }

    func Click(){

        let  BBTC = BBTViewController()

        BBTC.bbchange = { (title:String,coloer:UIColor) in

            self.title = title

            self.view.backgroundColor = coloer

        }

        self.navigationController?.pushViewController(BBTC, animated: true)

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}


第二个控制器是:

//

//  BBTViewController.swift

//  Swift_009

//

//  Created by 周双建 on 15/12/7.

//  Copyright © 2015 周双建. All rights reserved.

//


import UIKit


class BBTViewController: UIViewController {

    //定义一个闭包,带有两个参数

    var bbchange :((title:String,coloer:UIColor)->Void)?

    override func viewDidLoad() {

        super.viewDidLoad()

        self.view.backgroundColor = UIColor.greenColor()

        //创建一个按钮

        let  btn = UIButton(type: UIButtonType.Custom) as UIButton

        btn.frame = CGRectMake(30, 100, self.view.frame.size.width-60, 40)

        btn.setTitle("返回到第1个控制器", forState: UIControlState.Normal)

        btn.setTitleColor(UIColor.magentaColor(), forState: UIControlState.Normal)

        btn.addTarget(self, action: "bClick", forControlEvents: UIControlEvents.TouchUpInside)

        self.view.addSubview(btn)


        // Do any additional setup after loading the view.

    }

    func bClick(){

        bbchange?(title:"成龙",coloer:UIColor.redColor())

        self.navigationController?.popToRootViewControllerAnimated(true)

        

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    


    /*

    // MARK: - Navigation


    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */


}







2015-08-15 08:18:25 u012701023 阅读数 3040
//
//  AppDelegate.swift
//  TabbarController


import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        self.window!.backgroundColor = UIColor .whiteColor();
        //创建3个
        //创建第一个界面
        let vc1:UIViewController = FirstViewController();
        let nav1 = UINavigationController(rootViewController:vc1);
        
        let image1 = UIImage(named: "sharePanel_ic_hvr_qq");
        nav1.tabBarItem = UITabBarItem(title:"会话", image: image1, tag:1);
        
        
        let vc2:UIViewController = ScondViewController();
        let nav2 = UINavigationController(rootViewController:vc2);
        
           let image2 = UIImage(named: "sharePanel_ic_hvr_weibo");
          nav2.tabBarItem = UITabBarItem(title:"短信", image: image2, tag:2);
        
        let vc3:UIViewController = ThirdViewController();
        let nav3 = UINavigationController(rootViewController:vc3);
        
           let image3 = UIImage(named: "sharePanel_ic_hvr_weixin");
        nav3.tabBarItem = UITabBarItem(title:"设置", image: image3, tag:3);
        
        let arr = [nav1,nav2,nav3];
        
        let tabBarController = UITabBarController();
        tabBarController.viewControllers = arr;
        self.window!.rootViewController = tabBarController;
        self.window!.makeKeyAndVisible()
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

//
//  FirstViewController.swift
//  TabbarController
//


import Foundation
import UIKit

class FirstViewController: UIViewController {
     override func viewDidLoad() {
        super.viewDidLoad();
        self.view.backgroundColor = UIColor .purpleColor();
    }
}

//
//  ScondViewController.swift
//  TabbarController

import Foundation
import UIKit


class ScondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad();
        self.view.backgroundColor = UIColor .orangeColor();
    }
}

//
//  ThirdViewController.swift
//  TabbarController
//


import Foundation
import UIKit

class ThirdViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad();
        self.view.backgroundColor = UIColor .redColor();
    }
}


2016-10-28 10:11:36 zhonggaorong 阅读数 5333

1、最简单AB面正向传值

效果如下:


最简单的正向传值.gif


首先我们先创建两个视图控制器ViewController.swift和SubViewController.swift

设置第一个界面

首先在第一个界面创建好一个TextFeild,用来写我们要传的文字

import UIKit

class ViewController: UIViewController {

    let textField = UITextField()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.whiteColor()
        textField.frame = CGRectMake(7, 100, 400, 50)
        textField.borderStyle = .RoundedRect
        self.view.addSubview(textField)
    }
}

在这里我们设置当点击屏幕跳转到第二个界面
并且执行传值操作

在SubViewController里设置一个公开的属性去接收数据

var string: String?

在ViewController里设置点击屏幕时传值

 //当点击屏幕时执行该方法
 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

         //MARK:创建第二个界面的对象
        let svc = SubViewController()
        //MARK:通过属性来进行正向传值
        svc.string = self.textField.text


        //跳转到第二个界面
        self.presentViewController(svc, animated: true, completion: nil)

    }

在第二个界面里创建好一个label用来接收值

添加一个label控件

 //控件不公开
    private let textLabel = UILabel()
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.cyanColor()
        textLabel.frame = CGRectMake(7, 200, 400, 50)
        textLabel.textAlignment = .Center
        self.view.addSubview(textLabel)

在视图将要显示的时候将传进来的值赋值给控件

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        //在视图将要显示的时候,去将传进来的值,赋给控件
        self.textLabel.text = string
    }

当点击屏幕时,返回第一个界面

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //返回上一页面
        self.dismissViewControllerAnimated(true, completion: nil)
    }

2、利用属性进行AB页面的反向传值

效果如下:


简单反向传值.gif

首先我们先创建两个视图控制器ViewController.swift和SubViewController.swift

第一步

在ViewController里面设置好一个固定的Label,设置显示的文字为:Location Services,和一个显示状态的statusLabel

第二步

在SubViewController里定义一个属性,去接收返回值的目标对象

var vc: ViewController?

然后放置一个UISwitch,设置开关的相应方法

    //设置开关的响应方法
    func swAction(sw:UISwitch){

        //判断状态
        if sw.on {

        //MARK:此步骤实现反向传值,将状态值回传给A页面
            self.vc?.lsStatusLabel.text = "ON"
        }else{
            self.vc?.lsStatusLabel.text = "OFF"
        }

    }

第三步

在ViewController里面设置touchBegan方法

      override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
          //MARK:实例化一个第二个界面的对象
        let svc = SubViewController()

        //给B页面传值,告诉B回传数据的目标是谁
        svc.vc = self

        //点击屏幕时跳转到第二个界面
        self.presentViewController(svc, animated: true, completion: nil)
    }

3、利用NSUserDefult双向传值

效果如下:


NSUserDefault.gif

原理:NSUserDefaults是系统对plist文件封装好的一个类,我们可以通过这个类对文件进行读写,在在HomeDirectory/Library/preferences/XXX.userdefaults.plist下。利用NSUserDefaults的特性,将某一个界面要传出的值存入到plist文件中,然后再另一个界面从plist文件读出来,就完成了传值操作

第一步

创建好ViewController和SubViewController

在ViewController中布局好Label的位置

第二步

在SubViewController中创建好5个按钮,为每个按钮添加tag值,并且实现交替选中效果,代码如下:

 for i in 0..<5 {
            let button = UIButton(type: .System)
            button.setTitle("第\(i + 1)个按钮", forState: .Normal)
            button.frame = CGRectMake(7, CGFloat(150 + i * 100), 400, 100)
            //为每一个button设置tag值
            button.tag = 100 + i
            //点击事件
            button.addTarget(self, action: #selector(self.buttonAction(_:)), forControlEvents: .TouchUpInside)
            self.view.addSubview(button)
        }

设置点击事件,实现交替选中效果

 for i in 0..<5 {
            let btn = self.view.viewWithTag(100 + i) as! UIButton
            btn.selected = false
        }
        sender.selected = true

在点击事件中同时使用NSUserDefaults将该按钮的tag值写入plist文件,做成数据记录
首先获取NSUserDefaults对象,这个对象是一个单例对象

let userDefaults = NSUserDefaults.standardUserDefaults()

将按钮的tag值做成数据记录

let selectedIndex = String(sender.tag)

写入plist文件

userDefaults.setObject(selectedIndex, forKey: "selectedIndex")

回写文件

userDefaults.synchronize()

第三步

从ViewController的viewWillAppear函数中我们读取plist文件,并完成反向传值

首先获取NSUserDefaults的对象
let userDefaults = NSUserDefaults.standardUserDefaults()

读取出数据,获取出SubViewController中对应button的tag值

let si = userDefaults.objectForKey("selectedIndex")

此时的si是AnyObject类型,我们将他转化成int类型

let tag = si?.intValue

然后修改ViewController中的label的文字

self.label.text = "第\(tag! - 99)个按钮是选中转态"

到这儿,就完成了反向传值的过程,第二个界面的哪个button被选中在第一个界面就会显示出来,效果如下


NSUserDefaults正向.gif

但是,再次从第一个界面跳回第二个界面是,按钮就变成全部为未选中状态,下面就是实现执行正向传值

同样是获取NSUserDefaults对象,然后读取数据,最后获取tag值找到对象button,设置该button为选中状态,在这儿还需读者自行去完成接下来的内容

4、使用系统闭包反向传值

这种方式是使用系统自带的闭包

  self.presentViewController(UIViewController, animated: Bool) { 
            code
        }

这种传值方式传值会有延迟,因为是在执行完页面切换后再去进行传值
效果如下:


系统闭包传值.gif

第一步

首先创建好ViewController和SubViewController
viewController中布局好一个label用来显示接收到数据,在SubViewController中布局好一个TextFeild用来写数据

第二步

在SubViewController中创建一个接收属性

var vc: ViewController?

第三步

在ViewController中写touchBegan方法
获取第SubViewController对象,在presentViewController方法中打开闭包,在将ViewController传给SubViewController的vc

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let svc = SubViewController()
        //将视图控制器本身传过去,方便回传使用
        self.presentViewController(svc, animated: true) { 
            //这个方法是在弹出下一页面后执行
            svc.vc = self
        }
    }

第四步

在SubViewController中写touchBegan方法
在self.dismissViewControllerAnimated方法中打开闭包将属性tf中的文字回传给属性vc的textLabel

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.dismissViewControllerAnimated(true) {
            //利用这个闭包来回传数据
            self.vc!.textLabel.text = self.tf.text

        }
    }

5、自定义闭包传值

和使用系统闭包传值的思想相同,自定义闭包传值就是自己声明一个闭包,通过这个闭包来进行页面之间的相互传值
效果同第4种

第一步

创建好ViewController和SubViewController
分别在vc和subvc中布局好一个label和textFeild

在SubViewController中声明一个闭包

var backValueClusore:((text:String)->Void)?

第二步

在ViewController中写touchBegan方法
获取第SubViewController对象,在presentViewController方法中打开闭包,在将ViewController传给SubViewController的vc

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let svc = SubViewController()
        self.presentViewController(svc, animated: true, completion: nil)

        //MARK:将闭包中的text赋值给self.textLabel
        svc.backValueclusore = {(text:String)->Void in
            self.textLabel.text = text

    }

第三步

在SubViewController中写touchBegan方法
在self.dismissViewControllerAnimated方法中打开闭包将属性tf中的文字回传给属性vc的textLabel

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
         //MARK:直接执行闭包
        self.dismissViewControllerAnimated(true, completion: nil)

        self.backValueclusore!(text:self.tf.text!)



6、代理委托实现页面之间的反向传值

这一种方法就是运用协议实现传值,这种方式也是在工程中常用的一种传值方法。首先创建好ViewController和SubViewController,在ViewController中创建好一个展示信息的Label,在SubViewController中创建好一个TextFeild,我们实现在第二个界面点击屏幕时,将TextFeild中的文字传到第一个界面,然后让背景颜色变色。

效果如下:


代理传值.gif

第一步:

首先我们要弄清楚ViewController和SubViewController谁是代理方,谁是委托方。委托方制订协议,并且拥有一个代理,代理方准守协议,并且实现协议中的方法。因为是从SubViewController中向ViewController中传递信息,SubViewController需要让代理完成传值的动作,所以这里SubViewController便是委托方

在SubViewController中我们指定一个协议BackValueProtocol:

extension ViewController:BackValueProtocol {
    func backValue(text: String, color: UIColor){}
}

因为我们要传递文字和颜色,所以协议里的方法带有text:String 和color:UIColor 两个参数

第二步:

制定好协议之后,我们还要给SubViewController添加一个代理属性

var delegate: BackValueProtocol?

第三步:

然后就是给SubViewController指定一个代理人,当然,这里就是ViewController了
我们设置当点击屏幕时跳转到第二个界面,并且告诉第二个界面,ViewController就是他的代理方

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

         //获取第二个界面
        let svc = SubViewController()
        self.presentViewController(svc, animated: true, completion: nil)
        //MARK:告诉第二个界面ViewController就是他的代理
        svc.delegate = self
    }

第四步:

接下来就是在ViewController中实现协议中的方法了

extension ViewController:BackValueProtocol {
    func backValue(text: String, color: UIColor) {
    //让label的文字显示为传过来的 文字
        textLabel.text = text

        //让背景颜色改变为传过来的颜色
        self.view.backgroundColor = color
    }
}
效果如下:

第五步

最后就是执行传值操作了,我们设置在点击第二个界面时传值所以,在SubViewController的touchBegan里开始传值

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        //B页面根部不需要考虑传值的目标和方法具体是谁,直接去调用自己的属性即可
        //这种方式称为回调,让目标调用目标方法,参数为我传入的TextField的值
        let color  = UIColor.redColor()

        //MARK:让自己的代理去执行传值操作
        self.delegate?.backValue(self.tf.text!, color: color)
        self.dismissViewControllerAnimated(true, completion: nil)
    }

到此为止,整个的反向传值就完成了,整个步骤如下:

  1. 想好谁是委托方谁是代理方,委托方制定协议并拥有一个代理属性
  2. 代理方遵守协议并实现协议中的方法
  3. 告诉委托方谁是代理
  4. 委托方告诉代理方去执行协议中的方法

7、使用TargetAction实现传值

这种传值方式和使用代理传值有相似之处,大致的思想就是在有数据的界面进行传值开始的指令,在接收数据的界面完成实质的传值操作

效果如下:


TargetAction传值.gif

首先,同样ViewController和SubViewController,并分别设置好label和TextFeild

第一步

在SubViewController中我们设置两个属性:target和action

 //设置两个属性接收传值目标和方法
    //用来去接收传值的目标是任意目标
    var target: AnyObject?

    //用来去接收传值的方法
    var action: Selector?

第二步

在SubViewController中,当点击屏幕时发送传值指令

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

//B页面根部不需要考虑传值的目标和方法具体是谁,直接去调用自己的属性即可
        //MARK:这种方式称为回调,让目标调用目标方法,参数为我传入的TextField的值

        self.target?.performSelector(self.action!, withObject: self.tf.text )


        self.dismissViewController

第三步

在ViewController中我们要给SubViewController指定是指真正的target,真正的 action是什么。

同样。我们设置当点击屏幕时,将这些信息告诉给SubVIewController,显然,target是ViewController,action则是我们指定的某个实现方法

那么,我们首先要设定一个用来回传数据的方法

    //定义一个用来去回传数据的方法
    func backValue(string:String) {
        //通过传进来的参数,给label赋值
        textLabel.text = string
    }

然后将target和action告诉SubViewController

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //获取SubViewController
        let svc = SubViewController()
        //通过正向传值,来告诉B页面回调时需要用到的参数
        svc.target = self

   //MARK:将action告诉SubViewController

   //NSSelectorFromString 方法是将一个字符串方法转换成真正的方法名
        svc.action = NSSelectorFromString("backValue:")
        self.presentViewController(svc, animated: true, completion: nil)
    }

到此为止,当点击ViewController屏幕时,将taget和action告诉了第二个界面,在第二个界面点击屏幕时,执行了target action命令,实现了backValue方法,完成了完整的传值操作

8、使用系统单例去传值

这个方法就厉害了我的哥!使用UIApplication这个单例类去完成数据的存储,将需要传输的数据存储到一个公共的数据源中,任何一个界面的任何地方都可以使用里面的资源

效果图如下:


系统单例传值.gif

在工程中,我们对AppDelegate.swift文件都不陌生,这个文件配置好了window层,并且可以设置指定的很视图控制器,在AppDelegate中我们知道它遵守了UIResponder和UIApplicationDelegate协议,而UIApplication便是一个系统提供的单例类,AppDelegate虽然不是单例类 ,但是共享的数据可以存放到这个类中

第一步

在AppDelegate声明一个用来去和共享数据的数组,然后配置一个带有的VC1,VC2和VC3的TabBarController做为根视图控制器

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    //用来去共享数据的数组
    var datas = [String]()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        //给数组里加一个原始数据
        datas.append("AD")

        //配置window
        window?.frame = UIScreen.mainScreen().bounds
        window?.backgroundColor = UIColor.whiteColor()

        let vc = ViewController()
        vc.view.backgroundColor = UIColor.redColor()
        let vc1 = ViewController1()
        vc1.view.backgroundColor = UIColor.yellowColor()
        let vc2 = ViewController2()
        vc2.view.backgroundColor = UIColor.blueColor()

        //设置标题
        vc.title = "视图1"
        vc1.title = "视图2"
        vc2.title = "视图3"

        let tvc = UITabBarController()
        tvc.viewControllers = [vc,vc1,vc2]
        window?.rootViewController = tvc
        window?.makeKeyAndVisible()
        return true
    }

第二步

当点击屏幕时,添加数据到公共的数据源中并且读取出来
因为在VC1,VC2,VC3中的任何一个界面都可以完成相同操作,在这里只拿一个做展示

  1. 首先我们获取UIApplication的单例类
  2. 通过单例类获取AppDelegate
  3. 通过AppDelegate操作共享的数组

代码如下:

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        //获取单例
        let application = UIApplication.sharedApplication()

        //通过这个单例获取AppDelegate这个对象
        let appDelegate = application.delegate as! AppDelegate

        //通过这个AppDelegate来操作共享的datas数组
        appDelegate.datas.append("VC-\(n + 1)")
        print(appDelegate.datas)
    }

当点击屏幕时,我们可以看到控制台中打印出来了我们设置的初始值“AD”和新加入的值“VC-2”,

同样在VC2中我们使用同样的放法获取数据

import UIKit

class ViewController1: UIViewController {
    var n = 1
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //UIApplication 是一个单例类
        //AppDelegate并不是单例类,但是共享的数据放到了这个类里

        //获取单例
        let application = UIApplication.sharedApplication()

        //通过这个单例获取AppDelegate这个对象
        let appDelegate = application.delegate as! AppDelegate

        //铜鼓这个APPDelegate来操作共享的datas数组
        appDelegate.datas.append("VC1-\(n + 1)")
        print(appDelegate.datas)
    }
}

在控制台中我们看到VC1传入的数据和VC2自己传入的数据,实现了页面之间的传值

9、使用自定义的单例实现页面之间的传值

本方法和第8中方法的实质原理是一样的,共享一个公共的数据源数组,任何一个界面都可以通过单例找到这个数据源进而进行写入和读取的操作,只不过,这里我们使用了自己的单例。

首先将根视图控制器设置为带有三个界面的标签控制器

1、自定义一个单例

在工程中我们继承于NSObject新建一个SingleInstance单例类,在单例类中我们声明一个公共的数据源,并且提供一个公开用来去获取单例的方法

不会创建单例的小伙伴点这儿

//创建一个单例类
class SingleInstance: NSObject {


    //在单例类中,有一个用来共享数据的数组
    var datas = [String]()
    //创建一个静态或者全局变量,保存当前单例实例值
    private static let singleInstance = SingleInstance()
    //私有化构造方法
    private override init() {
        //给数组加一个原始数据
        datas.append("SI")
    }

    //提供一个公开的用来去获取单例的方法
    class func defaultSingleInstance() ->SingleInstance {
        //返回初始化好的静态变量值
        return singleInstance
    }
}

2、在VC1中写入并读取数据

当点击屏幕时,将数据传入公共数据源,并读出

class ViewController1: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    //MARK:-当点击屏幕时写入并读取数据
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //获取单例对象
        let si = SingleInstance.defaultSingleInstance()
        //给单例中的数组加一个数据
        si.datas.append("VC1")
        print(si.datas)
    }
}

3、在VC2中写入并读取数据

class ViewController2: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //获取单例对象
        let si = SingleInstance.defaultSingleInstance()
        //给单例中的数组加一个数据
        si.datas.append("VC2")
        print(si.datas)
    }
}

在VC2中同样可以通过单例找到数据源,并且实现了页面之间的传值

10、通过通知中心NSNotificationCenter传值

在这里我们实现用通知中心的方法实现从VC中向VC1和VC2中传值

通知传值类似于广播和接收信号的过程,我们在AppDelegate中共享一个公共的数据源,在传值的界面设置了一个公共的广播站,并且获取这个数据源,需要接收数据的页面就相当于一个收音机,一旦收到广播站的信号,便去执行相应的方法

1、在AppDelegate中我们共享一个数据源

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    //用来保存共享数据的数组
    var datas = [Int]()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
          window = UIWindow()
        window?.frame = UIScreen.mainScreen().bounds
        window?.backgroundColor = UIColor.whiteColor()

        let vc = ViewController()
        vc.title = "VC"

        let vc1 = ViewController1()
        vc1.title = "VC1"

        let vc2 = ViewController2()
        vc2.title = "VC2"

        let tvc = UITabBarController()
        tvc.viewControllers = [vc,vc1,vc2]
        window?.rootViewController = tvc
        window?.makeKeyAndVisible()
        return true
    }

2、在VC1和VC2中扩展一个成为观察者的方法,并设置接收到数据后需要执行的动作

扩展为观察者的方法

extension ViewController1{
    //成为观察者的方法
    func becomeObserver(){
        //先去获取通知中心的单例
        let notificationCenter = NSNotificationCenter.defaultCenter()
        //向通知中心去加入观察者
        notificationCenter.addObserver(self, selector: #selector(ViewController1.sum), name: "又有新数据啦!", object: nil)
    }
}

接收到信号后执行的动作

 //观察者的响应方法
    func sum(){
        let datas = ((UIApplication.sharedApplication().delegate)as!AppDelegate).datas
        var sum = 0
        for i in datas{
            sum += i
        }
        print("VC1计算求和得:\(sum)")
    }

完整代码如下:

class ViewController1: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
extension ViewController1{
    //成为观察者的方法
    func becomeObserver(){
        //先去获取通知中心的单例
        let notificationCenter = NSNotificationCenter.defaultCenter()
        //向通知中心去加入观察者
        notificationCenter.addObserver(self, selector: #selector(ViewController1.sum), name: "又有新数据啦!", object: nil)
    }
    //观察者的响应方法
    func sum(){
        let datas = ((UIApplication.sharedApplication().delegate)as!AppDelegate).datas
        var sum = 0
        for i in datas{
            sum += i
        }
        print("VC1计算求和得:\(sum)")
    }

}

3、回到AppDelegate中将VC1和VC2注册成为观察者

  //让vc1,注册成为观察者
  vc1.becomeObserver()
  //让vc2,注册成为观察者
  vc2.becomeObserver()

4、当点击VC屏幕时写入数据并发送通知

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
     //在这里,向数据源中去增加数据,并发送通知

        //随机生成一个数字
        let num = arc4random_uniform(100)

        //通过UIApplication获取单例类并获取数据
        ((UIApplication.sharedApplication().delegate) as! AppDelegate).datas.append(Int(num))

        //MARK-获取通知中心
        let nc = NSNotificationCenter.defaultCenter()
        //发送通知
         nc.postNotificationName("又有新数据啦!", object: nil)

    }

在控制台中我们就可以看见当点击VC的时候,VC1和VC2都执行了响应的方法

效果如下:


通知中心传值.gif

到此,页面传值的10种方法全部介绍完了,文中有描述不当之处希望大家包涵和指正,有需要源代码的伙伴们可以点击这儿下载!



文/Demoer(简书作者)
原文链接:http://www.jianshu.com/p/f1d3a7d0c00d
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。




2019-04-01 14:37:08 sinat_36206255 阅读数 796

iOS自定义通用可切换tab菜单页面

tab菜单页代码

import UIKit
let DQScreenWidth:CGFloat = UIScreen.main.bounds.size.width
let DQScreenHeight:CGFloat = UIScreen.main.bounds.size.height
let DQTitleFont:UIFont = UIFont.systemFont(ofSize: 15)//标题的大小
let DQTitleHeight:CGFloat = 50.0//标题滚动视图的高度
let DQUnderlineHeight:CGFloat = 4.0//自定义滑动条的高度
let DQColer:UIColor = UIColor(red: 14/255, green: 193/255, blue: 243/255, alpha: 1) //标题选中的颜色
let DQNavigationHeight:CGFloat = 0//导航栏的高度
let DQTabbarHeight:CGFloat = 50.0//Tabbar的高度
let DQButtonStartTag:Int = 2000

class DQBaseHomeViewController: UIViewController,UIScrollViewDelegate{
    
    var titleScrollView:UIScrollView?//标题滚动视图
    var contentScollView:UIScrollView?//管理子控制器View的滚动视图
    var selectButton:UIButton?//保存选中的按钮
    var titleSButtons:NSMutableArray = NSMutableArray.init()//保存标题按钮的数组
    var selectIndex:Int = 0//选中的下标
    var isIninttial:Bool = false//第一次加载的变量
    let btnScale:CGFloat = 0.0//用于做过度的效果
    var underline:UIView?//自定义的滑动条
    var willDisapperIndex = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        automaticallyAdjustsScrollViewInsets = false
        view.backgroundColor = UIColor.white
        setupTitleScrollViewFunction()
        setupContentScrollVewFunction()
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if !isIninttial {
            setupAllButtonTitle()
            setupUnderlineFunction()
        }
        selectIndex = willDisapperIndex
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        selectIndex = willDisapperIndex
        isIninttial = true
    }
    
    
    func setupTitleScrollViewFunction() -> Void{
        titleScrollView = UIScrollView.init(frame: CGRect(x: 0, y: DQNavigationHeight, width: DQScreenWidth, height: DQTitleHeight))
        titleScrollView?.showsHorizontalScrollIndicator = false
        titleScrollView?.scrollsToTop = false
        titleScrollView?.backgroundColor = UIColor.white
        self.view.addSubview(titleScrollView!)
    
    }
    func setupAllButtonTitle() -> Void {
        
        let count:Int = self.childViewControllers.count
        let btnW:CGFloat = DQScreenWidth/CGFloat(count)
        titleSButtons.removeAllObjects()
        for  i  in 0..<count {
            let button:UIButton = UIButton.init(type: .custom)
            let btnX:CGFloat = CGFloat(i)*btnW
            button.frame = CGRect(x: btnX, y: 0, width: btnW, height: DQTitleHeight-5)
            button.tag = DQButtonStartTag+i
            button.titleLabel?.font = DQTitleFont
            let vc:UIViewController = self.childViewControllers[i]
            button.setTitleColor(UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1), for: .normal)
            button.setTitleColor(UIColor(red: 14/255, green: 193/255, blue: 243/255, alpha: 1), for: .selected)
            button.setTitle(vc.title, for: .normal)
            titleScrollView?.addSubview(button)
            titleSButtons.add(button)
            button.addTarget(self, action: #selector(titleclickAction(sender:)), for: .touchUpInside)
            
        }
        dealBtnClickAction(sender: titleSButtons[selectIndex] as! UIButton)
        
        titleScrollView?.contentSize = CGSize.init(width: CGFloat(count)*btnW, height: DQTitleHeight)
        contentScollView?.contentSize = CGSize.init(width: CGFloat(count)*DQScreenWidth, height: DQScreenWidth-DQTitleHeight-DQNavigationHeight)
        
    }
    func setupUnderlineFunction(){
        if underline != nil {
            self.underline?.removeFromSuperview()
        }
        let firstTitleButton:UIButton = titleScrollView?.subviews[selectIndex] as! UIButton
        
        let underlineView = UIView.init()
        underlineView.frame = CGRect.init(x: 0, y: DQTitleHeight-DQUnderlineHeight, width: 70, height: DQUnderlineHeight)
        underlineView.backgroundColor = DQColer
        titleScrollView?.addSubview(underlineView)
        underline = underlineView
        
        firstTitleButton.titleLabel?.sizeToFit()
        
        underline?.frame.size.width = (firstTitleButton.titleLabel?.frame.size.width)! + 10
        underline?.center.x = firstTitleButton.center.x
        
        let lineLayer = UIView.init()
        lineLayer.backgroundColor = UIColor.init(red: 0.93, green: 0.93, blue: 0.93, alpha: 1.0)
        lineLayer.frame = CGRect.init(x: 0, y: DQTitleHeight-1, width: DQScreenWidth, height: 1)
        titleScrollView?.addSubview(lineLayer)
    }
    func setupContentScrollVewFunction() -> Void {
        contentScollView = UIScrollView.init(frame: CGRect.init(x: 0, y: DQTitleHeight+DQNavigationHeight, width: DQScreenWidth, height: DQScreenHeight-DQTitleHeight-DQTabbarHeight-DQNavigationHeight))
        self.view.insertSubview(contentScollView!, at: 0)
        contentScollView?.backgroundColor = UIColor.white
        contentScollView?.showsHorizontalScrollIndicator = false
        contentScollView?.isPagingEnabled = true
        contentScollView?.bounces = false
        contentScollView?.alwaysBounceVertical = false
        contentScollView?.scrollsToTop = false
        contentScollView?.delegate = self
    }
    
    func titleclickAction(sender:UIButton) -> Void {
          dealBtnClickAction(sender: sender)
    }
    
    func setupTitleCenterFunction(sender:UIButton) -> Void {
        var offsetX:CGFloat = sender.center.x - DQScreenWidth*0.5
        if offsetX<0 {
            offsetX = 0
        }
        
        let maxoffsetX = (titleScrollView?.contentSize.width)! - DQScreenWidth
        if offsetX>maxoffsetX {
            offsetX = maxoffsetX
        }
        
        titleScrollView?.setContentOffset(CGPoint.init(x: offsetX, y: 0), animated: true)
        
    }
    
    func setupOneChildViewController(index:Int) -> Void {
        if index>=self.childViewControllers.count {
            return
        }
        let vc:UIViewController = self.childViewControllers[index]
        if (vc.view.superview != nil) {
            return
        }
        
        let offX = CGFloat(index)*DQScreenWidth
        vc.view.frame = CGRect.init(x: offX, y: 0, width: DQScreenWidth, height: (contentScollView?.frame.size.height)!)
        contentScollView?.addSubview(vc.view)
        
        
    }
    func adjustUnderLine(sender:UIButton) -> Void {
        underline?.frame.size.width = (sender.titleLabel?.frame.size.width)!+10
        underline?.center.x = sender.center.x
        
    }
    func selectTitleButton(sender:UIButton) -> Void {
        selectButton?.setTitleColor(UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1), for: .normal)
        sender.setTitleColor(UIColor(red: 14/255, green: 193/255, blue: 243/255, alpha: 1), for: .normal)
        let scale:CGFloat = 1 + btnScale
        
        selectButton?.transform = CGAffineTransform.identity
        sender.transform = CGAffineTransform.init(scaleX: scale, y: scale)

        selectButton = sender
    }
    func dealBtnClickAction(sender:UIButton) -> Void {
        let index = sender.tag - DQButtonStartTag
        //willDisapperIndex = index
        //selectIndex = willDisapperIndex
        selectTitleButton(sender: sender)
        setupOneChildViewController(index: index)
        contentScollView?.contentOffset = CGPoint.init(x: CGFloat(index)*DQScreenWidth, y: 0)
        willDisapperIndex = index
        UIView.animate(withDuration: 0.25) { 
            
            self.adjustUnderLine(sender: sender)
            
        }
        for i in 0..<titleSButtons.count{
            if !(i==index){
                let noSelectBtn:UIButton = titleSButtons[i] as! UIButton
                noSelectBtn.setTitleColor(UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1), for: .normal)
            }
        }
        
        for i in 0..<childViewControllers.count{
            let chilaCtl:UIViewController = self.childViewControllers[i]
            if !chilaCtl.isViewLoaded {
                continue
            }
        
            let childVcView:UIView = chilaCtl.view
            if childVcView.isKind(of: UIScrollView.classForCoder()) {
                let scrollView:UIScrollView = childVcView as! UIScrollView
                scrollView.scrollsToTop = (i == index)
                if i == index {
                    
                }
            }
            
        }
    }
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let value = scrollView.contentOffset.x/DQScreenWidth
        let leftIndex:Int = Int(value)
        let rightIndex = leftIndex+1
        let scaleRight:CGFloat = scrollView.contentOffset.x/DQScreenWidth - CGFloat(leftIndex)
        let scaleLeft:CGFloat = 1 - scaleRight
        let leftTitleBtn:UIButton = self.titleSButtons[leftIndex] as! UIButton
        leftTitleBtn.dqButtonColorScale(scaleLeft)
        
        if rightIndex < self.titleSButtons.count {
            let rightTitleBtn:UIButton = self.titleSButtons[rightIndex] as! UIButton
            rightTitleBtn.dqButtonColorScale(scaleRight)
            rightTitleBtn.transform = CGAffineTransform.init(scaleX: scaleRight*self.btnScale+1, y: scaleRight*self.btnScale+1)
            
        }
        
        setupOneChildViewController(index: rightIndex)
    }
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let index:Int = Int(scrollView.contentOffset.x/DQScreenWidth)
        let button:UIButton = titleSButtons[index] as! UIButton
        willDisapperIndex = index
        dealBtnClickAction(sender: button)
    }
}

使用

import UIKit
import SnapKit

let GNScreenW = UIScreen.main.bounds.size.width
let GNScrennH = UIScreen.main.bounds.size.height

class CollectListViewController: DQBaseHomeViewController{
    
    let ctl1 = CommonCollectionViewController()
    let ctl2 = CommonCollectionViewController()
    let ctl3 = CommonCollectionViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "清单"
        
        ctl1.title = "收藏商品"
        ctl1.view.backgroundColor = UIColor.white
        
        ctl2.title = "常购商品"
        ctl2.view.backgroundColor = UIColor.white
        
        ctl3.title = "浏览记录"
        ctl3.view.backgroundColor = UIColor.white
        
        self.addChildViewController(ctl1)
        self.addChildViewController(ctl2)
        self.addChildViewController(ctl3)
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
}

效果图

在这里插入图片描述

界面之间传值

阅读数 515