首页 > 代码库 > 利用Swift之协议语法实现页面间的传值功能

利用Swift之协议语法实现页面间的传值功能

随着Swift 新开发语言的发布,又随着Xcode6.0.1的正式发布,利用swift编写iOS代码迫在眉睫,笔者在使用Objective-C开发近三年以来,对这种优雅的语法深感赞叹,下面我将对比式的实现一个页面传值的demo,使用语法是swift,页面传值是学习iOS初期必修的demo,因为涉及一个非常难懂的语法:协议和委托,这里涉及的swift语法和一些基本操作我不在一一赘述,如果方便可下载IT面试宝典APP,里面有对其详细介绍,那就开门见山吧,用代码实现以下功能:

1,创建Swift工程,可以使用XIB或纯代码,这里主要纯代码,大家会注意到这个奇怪的语言没有了.h文件,而是以.swift的文件

2,修改手机屏幕上的显示名称,这个和XCODE5 严重的不同,不知道是后退还是前进,笔者表示很无语,后面看看怎么恢复吧

3,基本的swift语法来定义:协议,正向传值和反向传值,即回调

4,简单的提下如何把XIB默认的改成纯代码,即删除XIB文件

5,页面功能是首页输入学号,然后点击注册,模态呈现注册页面,此时显示了上一个页面填入的学号,接着输入姓名后点击确定,返回上个页面显示名称

就这么多吧,下面来具体实现下,如果是新手可以照着步骤来做,遇到不明白的语法,请自行百度:


一,创建工程,总体代码结构如下图:

啥也不说了,进入下一步

二,纯代码构建首页面(HomeViewController.swift)和注册页面(RegisterViewController.swift)

class HomeViewController: UIViewController,RegisterDelegate {
    
    var nameLbl : UILabel!
    var numTF : UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.view.backgroundColor = UIColor.whiteColor()
        let titleItem : UINavigationItem = UINavigationItem(title: "首页")
        let NVC : UINavigationBar = UINavigationBar(frame: CGRectMake(0, 20, 320, 44))
        NVC.setItems([titleItem], animated: true)
        self.view.addSubview(NVC)
        
        
        
        numTF = UITextField(frame: CGRectMake(10, 100, 300, 35))
        numTF.placeholder = "输入学号"
        numTF.borderStyle = UITextBorderStyle.Line
        numTF.textAlignment = NSTextAlignment.Center
        numTF.clearButtonMode = UITextFieldViewMode.WhileEditing
        self.view.addSubview(numTF)
        
        nameLbl = UILabel()
        nameLbl.frame = CGRectMake(10, 150, 300, 40)
        nameLbl.text = ""
        nameLbl.backgroundColor = UIColor.lightGrayColor()
        nameLbl.textAlignment = NSTextAlignment.Center
        self.view.addSubview(nameLbl)
        
        
        
        let registerBtn : UIButton = UIButton()
        registerBtn.frame = CGRectMake(10, 200, 300, 40)
        registerBtn.backgroundColor = UIColor.lightGrayColor()
        registerBtn.setTitle("注册", forState: UIControlState.Normal)
        registerBtn.addTarget(self, action: "registerClick:", forControlEvents: UIControlEvents.TouchUpInside)
        self.view.addSubview(registerBtn)
        
    }

注意导航栏代码,以及各种UI的代码,很奇葩的写法,目前笔者只适配320的,没有做别的,大家可自行适配,这样一个首页UI就创建出来了,接着实现点击事件:

 func goRegister(){
        
        if numTF.text.isEmpty {
            
            var alert : UIAlertView = UIAlertView(title: "不能为空", message: "填写你的学号", delegate: nil, cancelButtonTitle: "知道了")
            alert.show()
            numTF.becomeFirstResponder()
            
        }else{
            
            var rootVC :RegisterViewController = RegisterViewController()
            let NVC :UINavigationController = UINavigationController(rootViewController: rootVC)
            self.presentViewController(NVC, animated: true, completion: nil)
        }
        
    }

这样就到了注册页面(RegisterViewController.swift),现在贴下注册页面代码:

class RegisterViewController: UIViewController,UITextFieldDelegate{

    var nameTF : UITextField!
    var num : String!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = UIColor.whiteColor()
        self.title = "注册"
        
        let leftItem : UIBarButtonItem? = UIBarButtonItem(title: "取消", style: UIBarButtonItemStyle.Plain, target: self, action: "back")
        self.navigationItem.leftBarButtonItem = leftItem
        
        
        let numLbl : UILabel = UILabel()
        numLbl.frame = CGRectMake(10, 100, 300, 40)
        numLbl.text = self.num
        numLbl.backgroundColor = UIColor.lightGrayColor()
        numLbl.textAlignment = NSTextAlignment.Center
        self.view.addSubview(numLbl)
        

       
        nameTF = UITextField(frame: CGRectMake(10, 150, 300, 35))
        nameTF.placeholder = "输入姓名"
        nameTF.textAlignment = NSTextAlignment.Center
        nameTF.borderStyle = UITextBorderStyle.Line
        nameTF.clearButtonMode = UITextFieldViewMode.WhileEditing
        nameTF.delegate = self
        self.view.addSubview(nameTF)
        
        
        var submitBtn : UIButton = UIButton(frame: CGRectMake(10, 210, 300, 40))
        submitBtn.backgroundColor = UIColor.lightGrayColor()
        submitBtn.setTitle("确定", forState: UIControlState.Normal)
        submitBtn.addTarget(self, action: "submitClick:", forControlEvents: UIControlEvents.TouchUpInside)
        self.view.addSubview(submitBtn)
    }

这里有个取消按钮,其他和首页一样,实现点击确认代码:

 func submitClick(sender : UIButton)
    {
        goBack()
    }
    
    func goBack(){
        
        if nameTF.text.isEmpty {
            
            var alert : UIAlertView = UIAlertView(title: "不能为空", message: "填写你的名字", delegate: nil, cancelButtonTitle: "知道了")
            alert.show()
            nameTF.becomeFirstResponder()
            
        }else{
                        
            self.dismissViewControllerAnimated(true, completion: { () -> Void in
                                
                println("我要确定了,你知道吗?");
            })
        }

    }
    
 
    
    //MARK: TFDELEGATE
    
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        
        goBack()
        
        return true
    }

    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.view.endEditing(true)
    }

这里代码也可注意了,多了一个点击view取消所以编辑响应事件

到这里页面之间就能相互切换进入了,具体的代码确实非常的不同,其中的swift语法和UI语法自行学习啦


三,创建协议

HomeViewController 文件里面编写代码如下:

import UIKit


protocol RegisterDelegate{
    func registerName(name : NSString)
}


class HomeViewController: UIViewController,RegisterDelegate {
    
    var nameLbl : UILabel!
    var numTF : UITextField!
........
  

注意要实现这个协议,然后实现协议方法如下:

   
    
    func registerName(name: NSString) {
        nameLbl.text = name
    }

    

了解object-C的朋友应该很明白这个步骤了,再这之前我们要在被委托的页面去实现一个协议对象,代码如下:

import UIKit

class RegisterViewController: UIViewController,UITextFieldDelegate{

    var nameTF : UITextField!
    var delegate : RegisterDelegate!
    var num : String!
    
    override func viewDidLoad() {
        super.viewDidLoad()
.....

注意这里的delegate,这就是协议委托对象,说白了就是要把之前的home页面这个对象传值过来赋予delegate,而delegate又遵循了协议,所以当delegate调用协议里面方法的时候就会再home页面里面由home来执行这个方法的实现过程,这样能达到把注册页面的值传到首页来显示的效果,这就是协议和委托配合使用的好处,好了,如果大家看到这里晕头了,请接着放下看,先不要管这句话了,我们回到home看看怎么设置代理的,代码如下,顺便看看我正向把学号传到注册页面去的代码:

 func goRegister(){
        
        if numTF.text.isEmpty {
            
            var alert : UIAlertView = UIAlertView(title: "不能为空", message: "填写你的学号", delegate: nil, cancelButtonTitle: "知道了")
            alert.show()
            numTF.becomeFirstResponder()
            
        }else{
            
            var rootVC :RegisterViewController = RegisterViewController()
            rootVC.delegate = self;
            rootVC.num = self.numTF.text
            
            let NVC :UINavigationController = UINavigationController(rootViewController: rootVC)
            
            self.presentViewController(NVC, animated: true, completion: nil)
        }
        
    }

然后我们再回到注册页面看看这个委托者到底在什么地方调用了协议方法:

   func goBack(){
        
        if nameTF.text.isEmpty {
            
            var alert : UIAlertView = UIAlertView(title: "不能为空", message: "填写你的名字", delegate: nil, cancelButtonTitle: "知道了")
            alert.show()
            nameTF.becomeFirstResponder()
            
        }else{
            
            self.delegate!.registerName(self.nameTF.text)
            
            self.dismissViewControllerAnimated(true, completion: { () -> Void in
                                
                println("我要确定了,你知道吗?");
            })

        }

    }


注意不同点啊,就是在不为空这里将姓名传递到协议方法的参数里面带到首页来显示,实现了一个回调传值的功能。


如果完成前面的几个步骤,你就可以测试是否能相互传值了,如果成功了,你可以休息休息了,下面就简单提下AppDelegate.swift里面我是怎么写的,注意啊,我把默认的ViewController.swift创建完成后删除了啊

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        self.window?.rootViewController = HomeViewController()
        
        
        return true
    }

第四步,纯代码替换Main.storyboard文件,先删除Main.storyboard

代码如下:

var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.backgroundColor = UIColor.whiteColor()
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController = HomeViewController()
        
        
        return true
    }

这样就等于是纯代码来实现了全部代码

第五步,修改显示名称

由于Xcode6 没有了InfoPlist.strings文件,这个你需要创建一个同名文件,又因为在info文件里面缺失了key:Bundle display name,这又要你手动添加,然后在InfoPlist.strings文件里面写入同Xcode5 一样的代码:

"CFBundleDisplayName" = "学号注册";

至此我们就实现了最初设定的全部功能,可以说这也是笔者的一次摸索,如此简单的一个demo却耗费了半天的时间,其中不乏对语法的查阅,功能的查找,确实来之不易,希望给读者带来效率,下面是实现效果图:


附录:转载本博客,请注明出处,维护版权,人人有责。



利用Swift之协议语法实现页面间的传值功能