MVC应用实战
iOS开发中设计模式是很重要的,其中,使用最多的就是MVC模式,今天就简单介绍一下在Swift中这么使用MVC模式来实现我们想要的功能;
模型-视图-控制器(Model-View-Controller,MVC)是Xerox PARC在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已广泛应用于用户交互应用程序中。在iOS开发中MVC的机制被使用的淋漓尽致,充分理解iOS的MVC模式,有助于我们程序的组织合理性。
1:模型对象
模型对象封装了应用程序的数据,并定义操控和处理该数据的逻辑和运算。例如,模型对象可能是表示游戏中的角色或地址簿中的联系人。用户在视图层中所进行的 创建或修改数据的操作,通过控制器对象传达出去,最终会创建或更新模型对象。模型对象更改时(例如通过网络连接接收到新数据),它通知控制器对象,控制器 对象更新相应的视图对象。
2:视图对象
视图对象是应用程序中用户可以看见的对象。视图对象知道如何将自己绘制出来,并可能对用户的操作作出响应。视图对象的主要目的,就是显示来自应用程序模型对象的数据,并使该数据可被编辑。尽管如此,在 MVC 应用程序中,视图对象通常与模型对象分离。
在iOS应用程序开发中,所有的控件、窗口等都继承自 UIView,对应MVC中的V。UIView及其子类主要负责UI的实现,而UIView所产生的事件都可以采用委托的方式,交给UIViewController实现。
3:控制器对象
在应用程序的一个或多个视图对象和一个或多个模型对象之间,控制器对象充当媒介。控制器对象因此是同步管道程序,通过它,视图对象了解模型对象的更改,反之亦然。控制器对象还可以为应用程序执行设置和协调任务,并管理其他对象的生命周期。
控制器对象解释在视图对象中进行的用户操作,并将新的或更改过的数据传达给模型对象。模型对象更改时,一个控制器对象会将新的模型数据传达给视图对象,以便视图对象可以显示它。
对于不同的UIView,有相应的UIViewController,对应MVC中的C。例如在iOS上常用的UITableView,它所对应的Controller就是UITableViewController。
1 import UIKit 2 3 class AppsModel: NSObject { 4 5 //定义模型的三个属性 6 var imageName:String! //图片名称 7 var appName:String! //应用名称 8 var appDescription:String! //应用描述 9 10 11 12 //自定义初始化方法 13 init(imageName image_Name:String , app_Name:String , app_Description:String) { 14 self.imageName=image_Name 15 self.appName=app_Name 16 self.appDescription=app_Description 17 } 18 19 20 21 // MARK: - NSCoding 22 func encodeWithCoder(_encoder: NSCoder) 23 { 24 _encoder.encodeObject(self.imageName, forKey: "M_imageName") 25 _encoder.encodeObject(self.appName, forKey: "M_appName") 26 _encoder.encodeObject(self.appDescription, forKey: "M_appDescription") 27 } 28 29 30 init(coder decoder: NSCoder) 31 { 32 // imageName = decoder.decodeObjectForKey("M_imageName") as String 33 // appName = decoder.decodeObjectForKey("M_appName") as String 34 // appDescription = decoder.decodeObjectForKey("M_appDescription") as String 35 36 //2015年5月2号修改 37 imageName = decoder.decodeObjectForKey("M_imageName") as! String 38 appName = decoder.decodeObjectForKey("M_appName") as! String 39 appDescription = decoder.decodeObjectForKey("M_appDescription") as! String 40 } 41 42 }
1 import UIKit 2 3 class MyTableViewCell: UITableViewCell { 4 5 var iconImageView:UIImageView! //图片 6 var appNameLabel:UILabel! //标题 7 var decLabel:UILabel! //描述 8 9 //赋值方法 - 显示cell内容方法 10 func showAppInfoWithModel(model:AppsModel) 11 { 12 //获取model中得图片 13 iconImageView.image = UIImage(named: model.imageName) 14 15 //获取model中app名称 16 appNameLabel.text = model.appName 17 18 //获取model中app描述 19 decLabel.text = model.appDescription 20 } 21 22 override init(style: UITableViewCellStyle, reuseIdentifier: String?) 23 { 24 super.init(style: style, reuseIdentifier: reuseIdentifier) 25 26 //创建iconImageView 27 iconImageView = UIImageView(frame: CGRectMake(10, 5, 40, 40)) 28 self.addSubview(iconImageView) 29 30 //创建appNameLabel 31 appNameLabel = UILabel(frame: CGRectMake(60, 0, 220, 15)) 32 appNameLabel.font = UIFont.systemFontOfSize(16) 33 self.addSubview(appNameLabel) 34 35 //创建decLabel 36 decLabel = UILabel(frame: CGRectMake(60, 15, 220, 35)) 37 decLabel.font = UIFont.systemFontOfSize(12) 38 decLabel.numberOfLines = 2 39 decLabel.textColor = UIColor.lightGrayColor() 40 self.addSubview(decLabel) 41 42 } 43 44 required init(coder aDecoder: NSCoder) { 45 fatalError("init(coder:) has not been implemented") 46 } 47 48 49 50 override func awakeFromNib() { 51 super.awakeFromNib() 52 // Initialization code 53 } 54 55 override func setSelected(selected: Bool, animated: Bool) { 56 super.setSelected(selected, animated: animated) 57 58 // Configure the view for the selected state 59 } 60 61 }
1 import UIKit 2 3 4 class UITableViewControllerCustom: UIViewController, UITableViewDataSource, UITableViewDelegate { 5 6 var titleString:String! 7 8 @IBOutlet var titleLabel:UILabel! 9 @IBOutlet var listTableView : UITableView! 10 11 12 //定义数组 13 var items:[AppsModel]! 14 15 16 //返回按钮事件 17 @IBAction func backButtonClick() 18 { 19 self.navigationController?.popViewControllerAnimated(true) 20 } 21 22 23 override func viewDidLoad() { 24 super.viewDidLoad() 25 26 titleLabel.text = titleString 27 28 //定义三个模型对象 29 var model1:AppsModel = AppsModel(imageName: "appIcon1.png", app_Name: "Football Maze", app_Description: "足球迷宫,迷宫的新玩法,益智虚拟迷宫游戏。快来挑战你的空间想象,足球迷宫带你到一个不同的世界… 迷宫大家都在玩,你还在等什么。") 30 var model2:AppsModel = AppsModel(imageName: "appIcon2.png", app_Name: "租房点评", app_Description: "租房被骗?现在开始,你来改变这一切!《租房点评》为你而备,租房无忧!") 31 var model3:AppsModel = AppsModel(imageName: "appIcon3.png", app_Name: "iJump", app_Description: "摇动手机,松鼠就可以运动啦,越跳越高,注意会有虫子咬坏跳板哦,祝你玩得开心") 32 var model4:AppsModel = AppsModel(imageName: "appIcon4.png", app_Name: "哪里逃", app_Description: "哪里逃 是一款躲避类游戏,拖动美女图片,躲避,追来的帅锅,帅锅人数越来越多,不要被追到哦。") 33 34 //修改数组值 35 items = [model1,model2,model3,model4] 36 37 //TabelView刷新 38 listTableView.reloadData() 39 40 // Do any additional setup after loading the view. 41 } 42 43 override func didReceiveMemoryWarning() { 44 super.didReceiveMemoryWarning() 45 // Dispose of any resources that can be recreated. 46 } 47 48 49 /* 50 // MARK: - Navigation 51 52 // In a storyboard-based application, you will often want to do a little preparation before navigation 53 override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { 54 // Get the new view controller using segue.destinationViewController. 55 // Pass the selected object to the new view controller. 56 } 57 */ 58 59 60 //MARK: - UITableViewDelegate 61 //tableView数据源:返回行数 62 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 63 { 64 return items.count 65 } 66 67 //tableView 数据源:每一行高度 68 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 69 { 70 return 50 71 } 72 73 //tableView数据源:每一行内容 74 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 75 { 76 //Cell标示符,代表一系列 77 // OC:使用static, swift:使用let 78 let cellIdentifier: String = "cellIdentifier" 79 80 //通过cellIdentifier标示符取没有使用的Cell 81 //有可能不存在,所以使用:optional 82 var cell: MyTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? MyTableViewCell 83 84 //如果cell取到是空 85 if cell == nil { // no value 86 87 //创建新的MyTableViewCell实例 88 //cell样式:UITableViewCellStyle.Default 89 //cell标示符:cellIdentifier 90 cell = MyTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: cellIdentifier) 91 92 //设置字体 93 // cell!.textLabel.font = UIFont.systemFontOfSize(14) 94 //2015年4月10号修改 95 cell!.textLabel?.font = UIFont.systemFontOfSize(14) 96 97 98 //设置选中cell样式 99 cell!.selectionStyle = .Gray; 100 101 //设置cell后面箭头样式 102 cell!.accessoryType = .DisclosureIndicator; 103 } 104 105 var cellModel:AppsModel = self.items[indexPath.row] 106 107 //通过自定义方法给cell赋值 108 cell?.showAppInfoWithModel(cellModel) 109 110 return cell!; 111 } 112 113 //tableView代理:点击一行 114 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 115 { 116 //释放选中效果 117 tableView.deselectRowAtIndexPath(indexPath, animated: true) 118 119 var urlString:String! = "https://itunes.apple.com/us/app/fruit-storm/id859713088?l=zh&ls=1&mt=8" 120 121 if indexPath.row == 0 122 { 123 urlString = "https://itunes.apple.com/us/app/football-maze/id879720177?l=zh&ls=1&mt=8" 124 }else if indexPath.row == 1 125 { 126 urlString = "https://itunes.apple.com/us/app/zu-fang-dian-ping/id893902071?l=zh&ls=1&mt=8" 127 }else if indexPath.row == 2 128 { 129 urlString = "https://itunes.apple.com/us/app/ijump/id877475648?l=zh&ls=1&mt=8" 130 }else if indexPath.row == 3 131 { 132 urlString = "https://itunes.apple.com/us/app/na-li-tao/id880016522?l=zh&ls=1&mt=8" 133 } 134 135 UIApplication.sharedApplication().openURL(NSURL(string: urlString)!) 136 } 137 }