iOS开发实践swift

Swift传值+视图跳转

2015-12-06  本文已影响5066人  Hinsverson

文章内容:

由于我最近正在进阶Swift的原因 控件都是手动创建。避免繁琐你可以在SB中直接创建并布局。

属性传值

简单实现一个demo

首先国际惯例,打开Xcode新建一个Project,选择SingleViewApplication 。然后在viewDidLoad中创建输入框和按钮

    //创建输入框
    textField = UITextField(frame: CGRectMake(0,200,200,30))
    textField.center.x = self.view.center.x
    textField.borderStyle = UITextBorderStyle.RoundedRect
  
    //创建按钮和对应的触发动作 添加到主视图上
    let button1 = UIButton(type: .System)
    button1.frame = CGRectMake(20,300,60,30)
    button1.setTitle("属性传值", forState: .Normal)
    button1.addTarget(self, action: "buttonAction1", forControlEvents: .TouchUpInside)
    
    let button2 = UIButton(type: .System)
    button2.frame = CGRectMake(20,300,60,30)
    button2.center.x = self.view.center.x
    button2.setTitle("代理传值", forState: .Normal)
    button2.addTarget(self, action: "buttonAction2", forControlEvents: .TouchUpInside)
    
    let button3 = UIButton(type: .System)
    button3.frame = CGRectMake(20,300,60,30)
    button3.center.x = self.view.frame.width - button1.center.x
    button3.setTitle("单例传值", forState: .Normal)
    button3.addTarget(self, action: "buttonAction3", forControlEvents: .TouchUpInside)
    
    self.view.addSubview(button1)
    self.view.addSubview(button2)
    self.view.addSubview(button3)
    self.view.addSubview(textField)

下面当然是添加按钮的触发方法

func buttonAction1(){

}

func buttonAction2(){
 
}

  
func buttonAction3(){

}

既然是不同界面之间的传值,那么除了系统默认的ViewController还需要再创建3个视图控制器。这里使用xib


重复步骤再创建2个xib(由于前面取名FirstVC 我这里分别取名为SecondVC和ThirdVC)
然后点按每个xib的File’s Owner 确保为对应的类(通过创建类文件同时创建xib 系统默认是绑定好了的 这里是为了保住万无一失)

考虑到刚学Swift的同学可能只接触过StoryBoard,没接触到xib。所以这里简单解释一下xib。

属性传值

我们通过在输入框中输入数据 然后点击按钮跳转到FirstVC 并通过一个标签显示输入的数据的方式实现属性传值。

首先打开FirstVC.Swift文件 添加一个属性

 var value:String!

修改viewDidLoad方法,建立标签和关闭按钮

 override func viewDidLoad() {
    super.viewDidLoad()
    
    let valueLable = UILabel(frame: CGRectMake(0,0,300,40))
    valueLable.center = self.view.center
    //显示传递的数据到lable
    valueLable.text = value
    
    let closeButton = UIButton(type: .System)
    closeButton.frame = CGRectMake(0, 30, 60, 30)
    closeButton.setTitle("关闭", forState: .Normal)
    closeButton.addTarget(self, action: "closeVC", forControlEvents: .TouchUpInside)
    
    self.view.addSubview(valueLable)
    self.view.addSubview(closeButton)
}

再实现关闭按钮的触发方法

func closeVC(){

    self.dismissViewControllerAnimated(true, completion: nil)
}

好了,终于要开始传值了。在ViewController.Swift中的buttonAction1方法中添加下面的代码

func buttonAction1(){

    let firstVC = FirstVC(nibName:"FirstVC",bundle: nil)
    
    firstVC.value = textField.text
    presentViewController(firstVC, animated: true, completion: nil)
}

解释一下:

顺便提一下另一个视图跳转的方法:

 performSegueWithIdentifier("Segue跳转名字", sender: self) 

如果你是用StoryBoard连线跳转实现传值请重写这个父类方法

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if(segue.identifier == "segue跳转名字")
    let firstVC = segue.destinationViewController as FirstVC
    firstVC.value = textField.text
 }

当然你也可以使用StoryBoard中视图的Identifier进行跳转。只需调用StoryBoard的instantiateViewControllerWithIdentifier方法获取实例对象 再结合presentViewController方法跳转 如下:

var firstVC = self.storyboard?.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController
    presentViewController(firstVC, animated: true, completion: nil)

当你有多个StoryBoard时 可以类比xib的实例对象获取方式

var storyboard = UIStoryboard(name: "New", bundle: nil)
var newVC = storyboard.instantiateViewControllerWithIdentifier("NewViewController") as NewViewController
presentViewController(newVC, animated: true, completion: nil)

代理反向传值

我们通过点击之前在ViewController上创建的代理传值按钮跳转到SecondVC,然后在SecondVC的输入框中输入数据 点击关闭按钮 在ViewController的输入框中显示数据的方式。

首先打开SecondVC.Swift文件添加全局textField

var textField:UITextField!

在viewDidLoad中添加下面代码 并在下面实现按钮关闭视图的方法

override func viewDidLoad() {
    textField = UITextField(frame: CGRectMake(0,200,200,30))
    textField.center.x = 187.5
    textField.borderStyle = .RoundedRect
    self.view.addSubview(textField)
    
    let closeButton = UIButton(type: .System)
    closeButton.frame = CGRectMake(0, 30, 60, 30)
    closeButton.setTitle("关闭", forState: .Normal)
    closeButton.addTarget(self, action: "closeVC", forControlEvents: .TouchUpInside)
    self.view.addSubview(closeButton)
}
func closeVC(){

       self.dismissViewControllerAnimated(true, completion: nil)
}

通过代理反向传值。通俗的说就是先定义一个protocol(协议)同时在协议里声明一个方法,然后在需要传值的A类中定义一个属性delegate(代理),类型为定义的协议类型。然后在A类的某个地方调用协议的方法。因为协议里的方法只进行了声明,并未具体实现。它将具体的实现交给遵循这个协议的B类。这样通过协议-代理的模式A类让B类 做了一些 A类想让B类做的事情。当然我们这里是进行传值(把SecondVC输入框中输入的数据传给ViewController并显示在textField上)这类似于其它编程语言里的接口。如下:



在SecondVC类的上面添加代码

protocol SecondVCDelegate{

func passOnInformation(VC:SecondVC,value:String)
}

在SecondVC类中添加代理属性

var delegate:SecondVCDelegate?

修改closeVC方法

func closeVC(){
    //判断代理是否为空
    if (self.delegate != nil) {
         //传值     
        self.delegate?.passOnInformation(self, value: textField.text!)
    }
    self.dismissViewControllerAnimated(true, completion: nil)
}

你一定要意识到 现在SecondVC的代理属性本来就为空,因为我们还没有设置它的代理 😂 在哪里设置呢?既然我们是先从默认的ViewController跳转到SecondVC 再从SecondVC反向传值到ViewController。所以跳转到SecondVC的时候是个绝佳的机会。

下面打开ViewController.Swift
首先继承SecondVCDelegate协议

class ViewController: UIViewController,SecondVCDelegate {

再修改buttonAction2方法

func buttonAction2(){

    let secondVC = SecondVC(nibName:"SecondVC",bundle: nil)
    //设置secondVC代理为自己
    secondVC.delegate = self
    presentViewController(secondVC, animated: true, completion: nil)
    
}

这时候你会发现系统会报错,为什么呢?还少了什么?
那就是我们还没有实现协议里的方法 (再次强调继承协议必须实现协议里的方法)

最后在buttonAction2方法下面实现

func passOnInformation(VC: SecondVC, value: String) {
    //接收数据
    self.textField.text = value
    
}

完美🙄

单例传值

首先解释一下IOS里的单例模式:
单例模式是一种常用的软件设计模式。它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。(来自百度--)

优点就不说了,可以自行百度

iOS中单例的创建方法

class AppInstance {
static let sharedInstance = AppInstance()
 
       private init() {} // 私有化init方法
}

例如下面这样构造将不会通过

var a1 = AppInstance() //不能通过

单例的使用方式

AppInstance.sharedInstance

不扯了,现在来通过单例传值。你可以自行创建一个单例🤔🤔🤔
当然还有更偷懒的方式,因为UIApplication就是一个单例,所以我们可以直接用它。

首先打开AppDelegate.Swift 在window属性下面添加一个value

var value:String?

再打开ThirdVC.Swift 在加载时给界面添加lable和关闭按钮 同时实现按钮的方法 和单例传值

override func viewDidLoad() {
    super.viewDidLoad()
    
    
    let closeButton = UIButton(type: .System)
    closeButton.frame = CGRectMake(0, 30, 60, 30)
    closeButton.setTitle("关闭", forState: .Normal)
    closeButton.addTarget(self, action: "closeVC", forControlEvents: .TouchUpInside)
    self.view.addSubview(closeButton)
    
    let lable = UILabel(frame: CGRectMake(0,200,100,30))
    lable.center.x = 187.5
    self.view.addSubview(label)

    //单例传值-接收数据
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    lable.text = appDelegate.value!

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

最后在ViewController的buttonAction3方法里添加代码

func buttonAction3(){

    //单例传值-传出数据
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.value = textField.text!
    //跳转视图
    let thirdVC = ThirdVC(nibName:"ThirdVC",bundle: nil)
    presentViewController(thirdVC, animated: true, completion: nil)    

}

单例还有很多 比如 NSUserDefaults 。它是一个轻量的经常用来保存数据的类,而且数据不会伴随App的退出而消失,当然也可以用来传值。它通过健-值对的方式存储和获取

 let userInfo = NSUserDefaults()
  userInfo.setValue(textField.text, forKey: "value")

 let userInfo = NSUserDefaults()  
 lable.text = userInfo.valueForKey("value") as! String

总结:

传值原理基本是都是通过先获取具体实例对象,然后通过某个属性或者媒介进行传值。

End

终于结束了😭 熬夜写的啊(头次写博文 有点慢😰)

上一篇下一篇

猜你喜欢

热点阅读