MVC应用实战

iOS开发中设计模式是很重要的,其中,使用最多的就是MVC模式,今天就简单介绍一下在Swift中这么使用MVC模式来实现我们想要的功能;

模型-视图-控制器(Model-View-Controller,MVC)是Xerox PARC在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已广泛应用于用户交互应用程序中。在iOS开发中MVC的机制被使用的淋漓尽致,充分理解iOSMVC模式,有助于我们程序的组织合理性。

1:模型对象

模型对象封装了应用程序的数据,并定义操控和处理该数据的逻辑和运算。例如,模型对象可能是表示游戏中的角色或地址簿中的联系人。用户在视图层中所进行的
创建或修改数据的操作,通过控制器对象传达出去,最终会创建或更新模型对象。模型对象更改时(例如通过网络连接接收到新数据),它通知控制器对象,控制器
对象更新相应的视图对象。
2:视图对象
视图对象是应用程序中用户可以看见的对象。视图对象知道如何将自己绘制出来,并可能对用户的操作作出响应。视图对象的主要目的,就是显示来自应用程序模型对象的数据,并使该数据可被编辑。尽管如此,在 MVC 应用程序中,视图对象通常与模型对象分离。

在iOS应用程序开发中,所有的控件、窗口等都继承自 UIView,对应MVC中的V。UIView及其子类主要负责UI的实现,而UIView所产生的事件都可以采用委托的方式,交给UIViewController实现。
3:控制器对象
在应用程序的一个或多个视图对象和一个或多个模型对象之间,控制器对象充当媒介。控制器对象因此是同步管道程序,通过它,视图对象了解模型对象的更改,反之亦然。控制器对象还可以为应用程序执行设置和协调任务,并管理其他对象的生命周期。

控制器对象解释在视图对象中进行的用户操作,并将新的或更改过的数据传达给模型对象。模型对象更改时,一个控制器对象会将新的模型数据传达给视图对象,以便视图对象可以显示它。

对于不同的UIView,有相应的UIViewController,对应MVC中的C。例如在iOS上常用的UITableView,它所对应的Controller就是UITableViewController。

    1. Model和View永远不能相互通信,只能通过Controller传递。
    2. Controller可以直接与Model对话(读写调用Model),Model通过Notification和KVO机制与Controller间接通信。
    3. Controller
      可以直接与View对话,通过outlet,直接操作View,outlet直接对应到View中的控件,View通过action向
      Controller报告事件的发生(如用户Touch我了)。Controller是View的直接数据源(数据很可能是Controller从
      Model中取得并经过加工了)。Controller是View的代理(delegate),以同步View与Controller。
 
首先我们新建一个项目,然后就可以开始来使用MVC来实现功能了。
 
模型:
 import UIKit

 class AppsModel: NSObject {

     //定义模型的三个属性
     var imageName:String!  //图片名称
     var appName:String!     //应用名称
     var appDescription:String!      //应用描述

     //自定义初始化方法
     init(imageName image_Name:String , app_Name:String , app_Description:String) {
         self.imageName=image_Name
         self.appName=app_Name
         self.appDescription=app_Description
     }

     // MARK: - NSCoding
     func encodeWithCoder(_encoder: NSCoder)
     {
         _encoder.encodeObject(self.imageName, forKey: "M_imageName")
         _encoder.encodeObject(self.appName, forKey: "M_appName")
         _encoder.encodeObject(self.appDescription, forKey: "M_appDescription")
     }

     init(coder decoder: NSCoder)
     {
 //        imageName = decoder.decodeObjectForKey("M_imageName") as String
 //        appName = decoder.decodeObjectForKey("M_appName") as String
 //        appDescription = decoder.decodeObjectForKey("M_appDescription") as String

         //2015年5月2号修改
         imageName = decoder.decodeObjectForKey("M_imageName") as! String
         appName = decoder.decodeObjectForKey("M_appName") as! String
         appDescription = decoder.decodeObjectForKey("M_appDescription") as! String
     }

 }
视图:
 import UIKit

 class MyTableViewCell: UITableViewCell {

     var iconImageView:UIImageView!   //图片
     var appNameLabel:UILabel!        //标题
     var decLabel:UILabel!            //描述

     //赋值方法 - 显示cell内容方法
     func showAppInfoWithModel(model:AppsModel)
     {
         //获取model中得图片
         iconImageView.image = UIImage(named: model.imageName)

         //获取model中app名称
         appNameLabel.text = model.appName

         //获取model中app描述
         decLabel.text = model.appDescription
     }

     override init(style: UITableViewCellStyle, reuseIdentifier: String?)
     {
         super.init(style: style, reuseIdentifier: reuseIdentifier)

         //创建iconImageView
         iconImageView = UIImageView(frame: CGRectMake(, , , ))
         self.addSubview(iconImageView)

         //创建appNameLabel
         appNameLabel = UILabel(frame: CGRectMake(, , , ))
         appNameLabel.font = UIFont.systemFontOfSize()
         self.addSubview(appNameLabel)

         //创建decLabel
         decLabel = UILabel(frame: CGRectMake(, , , ))
         decLabel.font = UIFont.systemFontOfSize()
         decLabel.numberOfLines =
         decLabel.textColor = UIColor.lightGrayColor()
         self.addSubview(decLabel)

     }

     required init(coder aDecoder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }

     override func awakeFromNib() {
         super.awakeFromNib()
         // Initialization code
     }

     override func setSelected(selected: Bool, animated: Bool) {
         super.setSelected(selected, animated: animated)

         // Configure the view for the selected state
     }

 }
控制器:
 import UIKit

 class UITableViewControllerCustom: UIViewController, UITableViewDataSource, UITableViewDelegate  {

     var titleString:String!

     @IBOutlet var titleLabel:UILabel!
     @IBOutlet var listTableView : UITableView!

     //定义数组
     var items:[AppsModel]!

     //返回按钮事件
     @IBAction func backButtonClick()
     {
         self.navigationController?.popViewControllerAnimated(true)
     }

     override func viewDidLoad() {
         super.viewDidLoad()

         titleLabel.text = titleString

         //定义三个模型对象
         var model1:AppsModel = AppsModel(imageName: "appIcon1.png", app_Name: "Football Maze", app_Description: "足球迷宫,迷宫的新玩法,益智虚拟迷宫游戏。快来挑战你的空间想象,足球迷宫带你到一个不同的世界… 迷宫大家都在玩,你还在等什么。")
         var model2:AppsModel = AppsModel(imageName: "appIcon2.png", app_Name: "租房点评", app_Description: "租房被骗?现在开始,你来改变这一切!《租房点评》为你而备,租房无忧!")
         var model3:AppsModel = AppsModel(imageName: "appIcon3.png", app_Name: "iJump", app_Description: "摇动手机,松鼠就可以运动啦,越跳越高,注意会有虫子咬坏跳板哦,祝你玩得开心")
         var model4:AppsModel = AppsModel(imageName: "appIcon4.png", app_Name: "哪里逃", app_Description: "哪里逃 是一款躲避类游戏,拖动美女图片,躲避,追来的帅锅,帅锅人数越来越多,不要被追到哦。")

         //修改数组值
         items = [model1,model2,model3,model4]

         //TabelView刷新
         listTableView.reloadData()

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

     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.
     }
     */

     //MARK: - UITableViewDelegate
     //tableView数据源:返回行数
     func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
     {
         return items.count
     }

     //tableView 数据源:每一行高度
     func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
     {

     }

     //tableView数据源:每一行内容
     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
     {
         //Cell标示符,代表一系列
         // OC:使用static,  swift:使用let
         let cellIdentifier: String = "cellIdentifier"

         //通过cellIdentifier标示符取没有使用的Cell
         //有可能不存在,所以使用:optional
         var cell: MyTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? MyTableViewCell

         //如果cell取到是空
         if cell == nil { // no value

             //创建新的MyTableViewCell实例
             //cell样式:UITableViewCellStyle.Default
             //cell标示符:cellIdentifier
             cell = MyTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: cellIdentifier)

             //设置字体
 //            cell!.textLabel.font = UIFont.systemFontOfSize(14)
             //2015年4月10号修改
             cell!.textLabel?.font = UIFont.systemFontOfSize()

             //设置选中cell样式
             cell!.selectionStyle = .Gray;

             //设置cell后面箭头样式
             cell!.accessoryType = .DisclosureIndicator;
         }

         var cellModel:AppsModel = self.items[indexPath.row]

         //通过自定义方法给cell赋值
         cell?.showAppInfoWithModel(cellModel)

         return cell!;
     }

     //tableView代理:点击一行
     func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
     {
         //释放选中效果
          tableView.deselectRowAtIndexPath(indexPath, animated: true)

         var urlString:String! = "https://itunes.apple.com/us/app/fruit-storm/id859713088?l=zh&ls=1&mt=8"

         {
             urlString = "https://itunes.apple.com/us/app/football-maze/id879720177?l=zh&ls=1&mt=8"
         }
         {
             urlString = "https://itunes.apple.com/us/app/zu-fang-dian-ping/id893902071?l=zh&ls=1&mt=8"
         }
         {
             urlString = "https://itunes.apple.com/us/app/ijump/id877475648?l=zh&ls=1&mt=8"
         }
         {
             urlString = "https://itunes.apple.com/us/app/na-li-tao/id880016522?l=zh&ls=1&mt=8"
         }

         UIApplication.sharedApplication().openURL(NSURL(string: urlString)!)
     }
 }
 
 
 
 
 
 
 
 
 
 
 

iOS开发——swift精讲&MVC应用实战的更多相关文章

  1. iOS开发Swift篇—(一)简单介绍

    iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C ...

  2. iOS开发Swift篇—(二)变量和常量

    iOS开发Swift篇—(二)变量和常量 一.语言的性能 (1)根据WWDC的展示 在进行复杂对象排序时Objective-C的性能是Python的2.8倍,Swift的性能是Python的3.9倍 ...

  3. iOS开发Swift篇—(三)字符串和数据类型

    iOS开发Swift篇—(三)字符串和数据类型 一.字符串 字符串是String类型的数据,用双引号""包住文字内容  let website = "http://www ...

  4. iOS开发Swift篇—(四)运算符

    iOS开发Swift篇—(四)运算符 一.运算符 1.Swift所支持的部分运算符有以下一些 赋值运算符:= 复合赋值运算符:+=.-= 算术运算符:+.-.*./ 求余运算符:% 自增.自减运算符: ...

  5. iOS开发Swift篇—(五)元组类型

    iOS开发Swift篇—(五)元组类型 一.元组类型介绍 1.什么是元组类型 元组类型由 N个 任意类型的数据组成(N >= 0),组成元组类型的数据可以称为“元素” 示例: let posit ...

  6. iOS开发Swift篇—(六)流程控制

    iOS开发Swift篇—(六)流程控制 一.swift中的流程控制 Swift支持的流程结构如下: 循环结构:for.for-in.while.do-while 选择结构:if.switch 注意:这 ...

  7. iOS开发Swift篇—(七)函数(1)

    iOS开发Swift篇—(七)函数 一.函数的定义 (1)函数的定义格式 func 函数名(形参列表) -> 返回值类型 { // 函数体... } (2)形参列表的格式 形参名1: 形参类型1 ...

  8. iOS开发Swift篇—(八)函数(2)

    iOS开发Swift篇—(八)函数(2) 一.函数类型 函数类型也是数据类型的一种,它由形参类型和返回值类型组成,格式是 (形参类型列表) -> 返回值类型 func sum(num1: Int ...

  9. iOS开发Swift篇—(九)属性

    iOS开发Swift篇—(九)属性 一.类的定义 Swift与Objective-C定义类的区别 Objective-C:一般需要2个文件,1个.h声明文件和1个.m实现文件 Swift:只需要1个. ...

随机推荐

  1. poj2436,poj3659,poj2430

    这两题都体现了dp的核心:状态 dp做多就发现,状态一设计出来,后面的什么都迎刃而解了(当然需要优化的还要动动脑筋): 先说比较简单的: poj2436 由题得知病毒种数<=15很小,于是我们就 ...

  2. bzoj4511: [Usaco2016 Jan]Subsequences Summing to Sevens

    前缀和. 设f[i]为前缀和%7=i的第一个点.那么答案就是max(i-f[s[i]%7])了. #include<cstdio> #include<algorithm> #i ...

  3. Spring--通过注解来配置bean

    Spring通过注解配置bean 基于注解配置bean 基于注解来配置bean的属性 在classpath中扫描组件 组件扫描(component scanning):Spring能够从classpa ...

  4. NGINX(四)配置解析

    前言 nginx配置解析是在初始化ngx_cycle_t数据结构时,首先解析core模块,然后core模块依次解析自己的子模块. 配置解析过程 nginx调用ngx_conf_parse函数进行配置文 ...

  5. HDU 4276-The Ghost Blows Light(树状背包)

    题意: n个房间,每个有一定的钱,一个房间到另一个房间花费一定的时间,给你房间连接树,求在t时间内到达房间m能得到的最大钱数(从房间1(根)出发) 分析: 该题关键是最后要到达m,没有这个条件,就是基 ...

  6. HDU 3335 Divisibility dancing links 重复覆盖

    分析: dlx重复覆盖的巧用,重复覆盖的原理恰好符合本题的筛选方式,即选择一个数后,该数的倍数或约数可以保证在之后的搜索中不会被选择 于是修改一下启发函数,求解最大的重复覆盖即可.   其实不一定不被 ...

  7. Python 连接mysql

    下面我们使用MySQLdb 实现连接mysql 数据库并进行操作. #!/usr/bin/env python # -*-coding:UTF-8-*- import MySQLdb def conn ...

  8. 如何查看.Net FrameWork,VC++ 等安装包的启动参数

    最近做了一个客户端的程序,客户端程序运行环境要求是.Net FrameWork 4.0 和VC++ 2012 ,在做安装包的时候需要先检测系统环境是否存在这些环境,不存在则安装对应环境. 使用工具来制 ...

  9. shell ftp上传下载文件

    1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地/home/databackup#### #!/bin/bash ftp -n<<! open ...

  10. android学习之activity

    Activity 的生命周期 和 J2ME 的 MIDlet 一样,在 android 中,Activity 的生命周期交给系统统一管理.与 MIDlet 不同的是安装在 android 中的所有的 ...