斯坦福大学公开课第四课 Views 视图
课程开始老师怀念了一会老乔。接着介绍这次的课程分为两部分,一部分是Calculator的Demo,一部分是Views.
课程开始到第四课,其实斯坦福的课程里是有作业的,人家已经做完了第一个作业了,就是完善计算器这个程序,完成一个比较复杂的计算器:
计算器大概要完整这么多的功能,有兴趣的同学可以把这个作业的pdf下载下来自己完成。下载地址:作业1
个人感觉这个计算器比较奇葩的地方是设计了一个Enter键。可能是为了减小程序的难度吧。
Demo的演示包括下面内容:
1、可编程性,添加一些API,作用是返回计算程序!Api要保证程序向上兼容。Brain是操作数和操作符的组合。通过类方法执行这个程序,也就是计算运算结果。
他说的计算程序,就是操作数和操作符的组合,把这个组合里的操作数和操作符弹栈并做相应的计算。
Api向上兼容就是说他没有改变Controller,程序一样能正常运行。
2、演示使用到了id类型、property 、数组的可变和不可变复制、内省、还有递归,一下子关联了这么多知识。
这位老师还强调,希望大家通过课程和作业,熟悉各个集合类的使用,熟悉Founation框架的使用,甚至熟悉和适应Obj-c。
用到id是,要用内省判断来包含id使用时不至于崩溃。
3、里面的描述的api留到作业了,应该就是把计算时的操作数和操作符 组合成字符串,这样Controller就可以把这些操作显示到view上。
4、课程提问讨论下nil判断包含的问题,老师说这是编码艺术的范畴,他喜好更少的代码,在确定不需nil判断时,尽量不要添加。我个人认为还是添加比较好,这样可以增加代码的可读性。这可能和人家大师的区别吧。
演示代码如下:
brain头文件:
- #import <Foundation/Foundation.h>
- @interface CalculatorBrain : NSObject
- - (void)pushOperand:(double)operand;
- - (double)performOperation:(NSString *)operation;
- @property (readonly) id program;
- + (double)runProgram:(id)program;
- + (NSString *)descriptionOfProgram:(id)promram;
- @end
brain的实现文件:
- #import "CalculatorBrain.h"
- @interface CalculatorBrain()
- @property (nonatomic, strong) NSMutableArray *programStack;
- @end
- @implementation CalculatorBrain
- @synthesize programStack = _programStack;
- - (NSMutableArray *)programStack
- {
- if (_programStack == nil) _programStack = [[NSMutableArray alloc] init];
- return _programStack;
- }
- - (id)program
- {
- return [self.programStack copy];
- }
- + (NSString *)descriptionOfProgram:(id)program
- {
- return @"Implement this in Homework #2";
- }
- - (void)pushOperand:(double)operand
- {
- [self.programStack addObject:[NSNumber numberWithDouble:operand]];
- }
- - (double)performOperation:(NSString *)operation
- {
- [self.programStack addObject:operation];
- return [[self class] runProgram:self.program];
- }
- + (double)popOperandOffProgramStack:(NSMutableArray *)stack
- {
- double result = 0;
- id topOfStack = [stack lastObject];
- if (topOfStack) [stack removeLastObject];
- if ([topOfStack isKindOfClass:[NSNumber class]])
- {
- result = [topOfStack doubleValue];
- }
- else if ([topOfStack isKindOfClass:[NSString class]])
- {
- NSString *operation = topOfStack;
- if ([operation isEqualToString:@"+"]) {
- result = [self popOperandOffProgramStack:stack] +
- [self popOperandOffProgramStack:stack];
- } else if ([@"*" isEqualToString:operation]) {
- result = [self popOperandOffProgramStack:stack] *
- [self popOperandOffProgramStack:stack];
- } else if ([operation isEqualToString:@"-"]) {
- double subtrahend = [self popOperandOffProgramStack:stack];
- result = [self popOperandOffProgramStack:stack] - subtrahend;
- } else if ([operation isEqualToString:@"/"]) {
- double divisor = [self popOperandOffProgramStack:stack];
- if (divisor) result = [self popOperandOffProgramStack:stack] / divisor;
- }
- }
- return result;
- }
- + (double)runProgram:(id)program
- {
- NSMutableArray *stack;
- if ([program isKindOfClass:[NSArray class]]) {
- stack = [program mutableCopy];
- }
- return [self popOperandOffProgramStack:stack];
- }
- @end
runProgram方法运行计算程序。
第二部分,Views
view的内容
这个是全新的课程。
1、View是屏幕上一个矩形的空间
2、View处理两件事:画出矩形控件,并处理其中的事件
3、view组织架构:View是层结构的,View只有superView,可以有多个subView。子view的顺序和数组中的位置有关系,数字越大,越显示在后面。
4、UIWindow ,iOS中,UIWindow没有那么重要了。交给view,viewcontroller处理。
views 组织架构
可以在通过工具来管理view的组织架构,也可以通过代码:
-(void)addSubView:(UIView *)aView;
-(void)removeFromSuperview;
需要注意点的是:
通过父view添加子view
通过子view自己移除自己
view的坐标系统
单位:
CGFloat ,是个float数字,在obj-c里就要用这个单位
CGPoint,是个C结构体,CGPoint p = CGPointMake(33.2.22.3); 表示位置。
CGSize, 是个结构体,表示大小。
CGRect :由一个 CGPoint和一个CGSize组成
用来描述view的主要四种类型。
坐标:
左上角是坐标的原点。
不用关心一个的点有都少像素,系统会自动适配。如果有需要获取一个点是多少像素,通过这个属性:@property CGFloat contentScaleFactor。
view有三个属性和它的位置大小有关:
CGRect bounds 自己内部的绘制空间。
下面两个属性是父类用来定位你的view的属性。
CGRect center
CGRect frame
为什么bounds和frame 不一样呢?因为view是可以伸缩,可以旋转的,看下图:
创建views
继承UIView。
通过alloc init 创建view .例子:
- CGRect labelRect = CGRectMake(20, 20, 50, 30);
- UILabel *label = [[UILabel alloc] initWithFrame:labelRect];
- label.text = @”Hello!”;
- [self.view addSubview:label];
每个controller都有一个顶级的view,其他view都放在这个view上。
什么时候需要自定义view呢?当需要特殊的图形,或控制触摸事件的时候
通常不要继承内置的控件。
drawRect
怎么绘图呢?覆盖一个方法:-(void)drawRect:(CGRect)aRect;
红色警告:决不能自己调用drawRect:。系统调用这个方法。如果你需要重绘怎么办?发送这两个消息
- - (void)setNeedsDisplay;
- - (void)setNeedsDisplayInRect:(CGRect)aRect;
绘制开销很大
如何利用drawRect呢?调用核心图形框架,它是C的接口,不是面向对象的。
Core Graphics framework的基本概念是,你创建一个环境,然后创建一些轨迹,比如直线和弧线,再设置他们都字体颜色样式等并描边或填充到轨迹里。这就是绘图的过程。
绘制图片和文字是主要的,文字和轨迹是一回事,它有很多精细的弧线组成。
绘制图片是赋值二进制码。
context(环境) ,决定了你要在哪绘制。
每次drawRect是的环境都是不一样的,所以不要缓存context。
获取环境的代码:
- CGContextRef context = UIGraphicsGetCurrentContext();
几乎所有的drawRect都把这个放在第一行。
- CGContextBeginPath(context);
- CGContextMoveToPoint(context, 75, 10);
- CGContextAddLineToPoint(context, 160, 150);
- CGContextAddLineToPoint(context, 10, 150);
- [[UIColor greenColor] setFill];
- [[UIColor redColor] setStroke];
- CGContextDrawPath(context,kCGPathFillStroke); //kCGPathFillStroke is a constant
上面代码:绘制的过程,先开始一个轨迹,移动轨迹的点,添加线,填充绿色,描边是红色, 颜色不需要指定context,默认就是当前的context。
调用 CGContextDrawpath在屏幕上画出来。
可以定义一个轨迹保存,在其他环境重用。
透明:
- @property CGFloat alpha
- @property BOOL opaque
alpha 1,不透明, 0透明。
- @property (nonatomic) BOOL hidden;
隐藏view。
画文字
- UIFont *myFont = [UIFont systemFontOfSize:12.0];
- UIFont *theFont = [UIFont fontWithName:@“Helvetica” size:36.0];
- NSArray *availableFonts = [UIFont familyNames];
最后一个获取可用的字体。
- NSString *text = ...;
- [text drawAtPoint:(CGPoint)p withFont:theFont]; // NSString instance method
因为UIKit,所以NSString也能实现UI上的功能,用了categories .
画图像
- UIImage *image = [UIImage imageNamed:@“foo.jpg”];
二进制,网络
- UIImage *image = [[UIImage alloc] initWithContentsOfFile:(NSString *)fullPath];
- UIImage *image = [[UIImage alloc] initWithData:(NSData *)imageData];
- UIGraphicsBeginImageContext(CGSize);
- // draw with CGContext functions
- UIImage *myImage = UIGraphicsGetImageFromCurrentContext();
- UIGraphicsEndImageContext();
- [image drawAtPoint:(CGPoint)p];
- [image drawInRect:(CGRect)r];
- [image drawAsPatternInRect:(CGRect)patRect;
drawAtPoint 会按原大小画出来
容芳志 (http://blog.csdn.net/totogo2010)
本文遵循“署名-非商业用途-保持一致”创作公用协议
斯坦福大学公开课第四课 Views 视图相关推荐
- 斯坦福大学公开课:iPhone开发教程2010年冬
2019独角兽企业重金招聘Python工程师标准>>> 斯坦福大学公开课:iPhone开发教程2010年冬 http://v.163.com/special/opencourse/i ...
- 【斯坦福大学公开课CS224W——图机器学习】三、节点和图嵌入
[斯坦福大学公开课CS224W--图机器学习]三.节点和图嵌入 文章目录 [斯坦福大学公开课CS224W--图机器学习]三.节点和图嵌入 1. 节点嵌入 1.1 编码器与解码器 1.2 节点嵌入的游走 ...
- 【斯坦福大学公开课CS224W——图机器学习】五、消息传递和节点分类
[斯坦福大学公开课CS224W--图机器学习]五.消息传递和节点分类 文章目录 [斯坦福大学公开课CS224W--图机器学习]五.消息传递和节点分类 1. Message Passing and No ...
- 斯坦福大学公开课 :机器学习课程
共20讲 在网易公开课上有视频全集,难能可贵的是配带中英文字幕 斯坦福大学公开课 :机器学习课程 在JerryLead的blog中可以下到他的学习笔记以及讲义原稿. 感谢Andrew Ng, 感谢Je ...
- 斯坦福大学公开课:iOS 8开发
斯坦福大学公开课:iOS 8开发: http://open.163.com/special/opencourse/ios8.html
- SCI论文如何写--斯坦福大学公开课-Writing in the Sciences
SCI论文如何写--斯坦福大学公开课-Writing in the Sciences 链接:https://pan.baidu.com/s/1McDHMLqhs-KbpKRDNRNQTQ 提取码:12 ...
- iPhone应用开发视频教程-斯坦福大学公开课
以下是一套由美国斯坦福大学(Stanford University)在2013年初推出的一套iPhone应用程序开发视频教程,详细讲解了iPhone4/iPhone4s/iPhone5/iPad等iO ...
- 斯坦福大学公开课 :机器学习课程(Andrew Ng)——1、整体看一看
============================================================================[课程综述]================== ...
- 斯坦福大学公开课机器学习:advice for applying machine learning | learning curves (改进学习算法:高偏差和高方差与学习曲线的关系)...
绘制学习曲线非常有用,比如你想检查你的学习算法,运行是否正常.或者你希望改进算法的表现或效果.那么学习曲线就是一种很好的工具.学习曲线可以判断某一个学习算法,是偏差.方差问题,或是二者皆有. 为了绘制 ...
- 学习笔记 吴恩达 斯坦福大学公开课 :机器学习课程-1 机器学习的动机与应用
机器学习的动机与应用 1,机器学习的定义 1959:"Field of study that gives computers the ability to learn without bei ...
最新文章
- react-native安装Ant Design
- 飞书在线文档 美誉度国内最佳!一起来围观~
- 专家点评Science:中英合作揭示拟南芥三萜化合物特异调控根系微生物组
- 1118 实验三 有限自动机的构造与识别
- Photoshop CC2018软件安装资料及教程
- 人脸识别翼闸使用规范_人行通道闸如何搭配人脸识别使用
- Linux中断与进程切换,结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程...
- Spring Boot——获取上传文件的MD5值解决方案
- 兼容ie浏览器的placeholder的几种方法
- ExtJs 备忘录(1)—— Form表单(一) [ 控件使用 ]
- SPOJ - SUBLEX 【后缀自动机】
- XSSFWorkbook 设置单元格样式_如何设置Excel单元格才能只输入数字!
- 【作者解读】ERNIE-GEN : 原来你是这样的生成预训练框架!
- linux 用户设密码,linux 上添加用户,设置密码
- php debug pit,start.php
- Windows便签快捷键
- C++中set用法详解
- mysql distinct count_MySQL中distinct和count(*)的使用方法比较
- 使用Python自动生成带有图表文字的PDF(附带万字完整代码)
- 问个问题(nimultisim14.0双开关)