【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记23 多MVC模式Demo的实现

简介: 上一话我们对Demo的选择界面做了自动布局的相关处理,现在开始连接多个MVC的操作。首先我们需要其他工程中的文件,那么让我们打开另一个app。

上一话我们对Demo的选择界面做了自动布局的相关处理,现在开始连接多个MVC的操作。首先我们需要其他工程中的文件,那么让我们打开另一个app。点击下面这个文件


然后拖动我们需要的文件到新的工程目录下:


注意勾选第一行,不然只是做了引用,如果你不小心删除了目标目录的话,你就找不到这些文件了,所以还是推荐做复制,这样会把文件复制到我们自己的工程目录下。

那么storyboard中的内容怎么办呢,我们只需要在原工程的storyboard中选中控制器然后复制,粘贴到新工程的storyboard中即可。

我注意到一个问题,当我复制粘贴过来的时候控制器中的脸没有了。看起来需要一些触发的小动作。我们来到FaceView中做一些小修改然后回退再保存就好了。


看,现在出来了。现在把这两个MVC添加到分栏控制器中,别忘了把左侧的小箭头移到分栏控制器中,具体做法我们之前已经介绍过了,这里就不啰嗦了,直接看结果:


我们在ip6 plus上运行一下,如果是竖屏你会看到:


跟其他尺寸的iphone一样,即便你左右滑动也不会出现笑脸,但是如果你横屏的话会看到:


这和ipad上的效果是相同的,我们之前讲过ip6 plus比较特殊,虽然屏幕小但是清晰度很高,在横屏模式下和ipad是一样的,关于自动布局的东西以后会细讲。

在我们继续下面的工作前需要修改storyboard以适应iphone,之前讲过我们在master上Embed in一个导航控制器,现在在iphone6上运行你会看到初始界面变成:

点击返回就可以回到选择界面,如果你在导航栏上加了一个标题,storyboard中会出现警告,原因是我们新加的导航栏会挡住之前的label,依旧update frame就好了。现在我们把master和detail关联起来。我们使用segue,之前讲过了拖拽按钮到小人脸的控制器上然后选择show detail,三个按钮都做重复的动作,三个segue分别命名为sad 、happy、meh(即不开心也不难过)。


现在你在iphone上运行可以看到点击按钮页面发生跳转了,说明segue生效了,但是小人脸的表情并没有发生变化,因为我们还没有准备segue,回忆一下之前讲的。

回到PsychologistViewController的代码中,我们在这个代码中所需要做的就是为segue做准备。

import UIKit

class PsychologistViewController: UIViewController {
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let hvc = segue.destinationViewController as? HappinessViewController,let identifier = segue.identifier{
            switch identifier{
            case "sad":hvc.happiness = 0
            case "happy":hvc.happiness = 100
            default:hvc.happiness = 50
            
            }
        
        
        }
    }

}

请注意我这里if let(可选绑定)的写法,这是Swift 1.2版本的新写法,避免了有很多if let{}嵌套的情况。看起来一切都很美好?那么运行一下点击一个按钮,你会发现程序崩溃了。中控台提示在解包一个可选型的时候发现了空值。错误定位到了updateUI这里:


你会看到faceView是空值。回顾一下之前的代码,我们刚才修改了happiness的值,来看看happiness的属性观察器:

 var happiness:Int = 75 {//0代表伤心,100代表开心
        didSet{
            happiness = max(min(happiness, 100), 0)
            println("happiness = \(happiness)")
            updateUI()
        }
    }

你会发现这里调用了updateUI方法,而这个方法中的faceView是用IBOutlet定义的!

这就是我们之前讲过的,outlet在segue的时候还没有初始化。

那么如何解决这个问题呢?幸运的是当我们想要修改模型的值时会更新页面的内容,如果这个时候页面的outlet没有值的话,只要忽略就好了。很简单的做法,我们把可能为空的值放入可选链中:

 func updateUI(){
    faceView?.setNeedsDisplay()
    }

意思是如果faceView为空,那么后面的都不会被执行。只需要这么一个简单的问号,再次运行你会发现得到了我们想要的效果。现在我们给detail部分也增加一个导航控制器,并且标题根据点击按钮的值得不同来设定。依旧Embed In一个。

然后在updateUI这个方法中增加一行:

 func updateUI(){
    faceView?.setNeedsDisplay()
    title = "\(happiness)"
    }

我们之前讲的控制器中有属性传达给它的导航控制器,然后控制器负责绘制,运行看看,你会发现标题是不会出现的:

这也是我们之前讲的,当你增加了一个导航控制器后,所有的segue都指向了导航控制器,而不再是detail本身了:


那么如何修改呢?

import UIKit

class PsychologistViewController: UIViewController {
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        var destination = segue.destinationViewController as? UIViewController
        if let navCon = destination as? UINavigationController{
        destination = navCon.visibleViewController
        }
        if let hvc = destination as? HappinessViewController,let identifier = segue.identifier{
            switch identifier{
            case "sad":hvc.happiness = 0
            case "happy":hvc.happiness = 100
            default:hvc.happiness = 50
            
            }
        
        
        }
    }

}

这里我们做了一个判断,当我们不确定某个控制器是否在导航控制器中的时候,我们可以应用这种写法。如果有导航控制器那么取出控制器中的最上面的控制器也就是Demo中的HappinessViewController,把它赋给destination,如果没有就把segue中保存的目标控制器赋给destination。现在可以运行了:


之前的segue都是我们通过storyboard中实现的,现在让我们来试试如何通过代码来实现,我们新加一个按钮取名Noting!然后通过页面间的拖动来产生segue。我们选中master控制器上方的黄色按钮


拖拽到detail的导航控制器中松手选择show detail。取名为nothing,然后我们打开联合视图拖动nothing按钮到控制器代码中生成一个action,action代码如下:

@IBAction func nothing(sender: UIButton) {
        performSegueWithIdentifier("nothing", sender: nil)
    }

可以看到我们让sender为nil代表点击这个按钮什么都没做,但是它依旧会执行到prepareForSegue方法,此时我们在prepareForSegue方法中增加一个case:

case "nothing":hvc.happiness = 25

运行你会发现nothing按钮依旧起作用了。



那么我们为什么要在代码中使用segue呢,你可能在按钮被点击之后需要根据一些状态来判断使用哪个segue,这是在代码中使用segue的经典理由。




目录
相关文章
|
前端开发 iOS开发
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记3 Xcode、Auto Layout及MVC
   继续上一话中的计算器Demo,上一话讲到类必须被初始化,类中的属性也必须被初始化,所以你不能只声明而不给它一个处置,那么问题来了,我们从storyboard中拖拽的@IBOutlet为什么只有声明而不需要初始化呢,这是因为它的类型依旧是一个optional,在你初始化之前已经被赋值为nil了,这也就是为什么你不需要再初始化它的原因。
934 13
|
前端开发 API
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记4 MVC enum Tuple Dictionary
 回顾一下我们上一话中的代码: @IBAction func operate(sender: UIButton) { let operation = sender.
833 0
|
Unix iOS开发
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记1 IOS8概述
  首先感谢网易公开课和SwiftV课堂的朋友们辛苦翻译,这个系列是我学习斯坦福IOS8公开课的个人心得体会和笔记,希望能给大家带来启发。
1121 0
|
10月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
8月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
475 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
7月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
224 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
9月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
284 66
|
7月前
|
人工智能 程序员 API
iOS|记一名 iOS 开发新手的前两次 App 审核经历
啥,这玩意也有新手保护期?
145 0
|
9月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
850 11
|
9月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
299 3