viewController.h文件:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface ViewController : UIViewController
{
//建立文本框
IBOutlet UITextField *textField;
//建立标签显示文字
IBOutlet UILabel *label;
}
@property(nonatomic, retain) UITextField *textField;
@property(nonatomic, retain) UILabel *label;
-(IBAction)Click:(id)sender;
@end
ViewController.m文件:
#import "ViewController.h"
@implementation ViewController
@synthesize textField, label;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 把已经读取的Label标签的文字替换成为本程序的显示内容
label.text = @"请输入文字";
}
-(IBAction)Click:(id)sender
{
int textCount = textField.text.length;
//当长度大于30
if (textCount > 30) {
//输出结果
label.text = @"Invalid Inputs";
//输入文字清空
textField.text = NULL;
}
// 如果长度不大于30
else {
//输出结果
NSString *result = [NSString stringWithFormat:@"输入长度为:%d", textCount];
label.text = result;
//清空文字
textField.text = NULL;
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
-(void) didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
//释放程序使用过的标签
-(void) dealloc
{
[label release];
[textField release];
//执行内存清理
[super dealloc];
}
@end
连接控件:
在textField属性中的placeholder可填入提示信息,效果如下:
连接控件:
运行程序:
总结:
这次学习的程序是运用textField.text.length输出长度,用NSString编写文字代码输入到Label控件中,使用Click方法对interface Builder内的Button控件和Label进行动态连接。点击Button控件对TextField内的文字数进行统计,Label控件显示计算结果。
我估计很少人知道这个库伯勒-罗丝模型或读过伊丽莎白‧库伯勒-罗丝的《论死亡与临终》这本书。先让大家了解一下这个模型。
什么是“库伯勒-罗丝模型”库伯勒-罗丝模型(Kübler-Ross model)描述了人对待哀伤与灾难过程中的5个独立阶段。绝症患者被认为会经历这些阶段。这一模型是伊丽莎白‧库伯勒-罗丝在她1969年出版的“论死亡与临终”(On Death and Dying)一书中提出的。这一模型中的阶段后来广泛流传,被称作“哀伤的五个阶段”(Five Stages of Grief)。
库伯勒-罗丝模型的五个阶段库伯勒-罗丝模型五个阶段包括:
库伯勒-罗丝把该模型应用到所有灾难性的个人损失上(工作、收入、自由),也包括家人的逝去,甚至离婚。她也提出这些阶段不一定按特定顺序发生,病人也不一定会经历其中所有阶段,但是她认为病人至少会经历其中两个阶段。
“库伯勒-罗丝模型”和软件纠错的六个阶段你可能会奇怪,库伯勒-罗丝模型跟软件开发有什么关系。事情是这样的,一个朋友告诉我说,他在一篇文章里看到有人把软件调试分为六个阶段,分别是:
你发现没有,完全可以将库伯勒-罗丝模型应用到这种事情上:
有没有发现自己也是这样?
前面的文章里,基本上都忽略了顶点的z坐标和w坐标,直接把OpenGL当做2D API来使用,本篇文章介绍一下w坐标的用处。
透视为了在2D的屏幕上表现出3D效果,OpenGL使用的是一种叫做透视的古老技术。说的更具体一点,Vertex Shader处理后的顶点坐标,并不是直接被OpenGL使用,而是还要经过Perspective Division处理。也就是说x、y和z坐标会被w除,w越大,得到的结果就越小,也就越接近0,看上去就越远。
代码和效果在OpenGL Console里执行下面的脚本:
import java.nio.ByteBuffer import java.nio.ByteOrder import javax.media.opengl.GL import org.glob.math.Matrix4f // projection matrix float aspectRatio = (width>height ? width/height : height/width) def projectionMatrix = (width > height) ? Matrix4f.orthoM(-aspectRatio, aspectRatio, -1f, 1f, -1f, 1f) : Matrix4f.orthoM(-1f, 1f, -aspectRatio, aspectRatio, -1f, 1f) // shaders def vertexShaderCode = """ uniform mat4 u_Matrix; attribute vec4 a_Position; void main() { gl_Position = u_Matrix * a_Position; } """ def fragmentShaderCode = """ #ifdef GL_ES precision mediump float; #endif void main() { gl_FragColor = vec4(0.5, 0.8, 0.3, 1.0); } """ def shaderProgram = glob.compileAndLink(vertexShaderCode, fragmentShaderCode) def aPositionLocation = shaderProgram.getAttribLocation("a_Position") shaderProgram.use() shaderProgram.getUniform("u_Matrix").setMatrix4fv(projectionMatrix.floats) // vertex data def BYTES_PER_FLOAT = 4 def POSITION_ELEMENT_COUNT = 4 def POINT_COUNT = 4 def vertices = [ // triangle fan // x y z w -0.5f, -0.5f, 0, 1, -0.5f, 0.5f, 0, 2, 0.5f, 0.5f, 0, 2, 0.5f, -0.5f, 0, 1, ] as float[] def vertexData = ByteBuffer .allocateDirect(vertices.length * BYTES_PER_FLOAT) .order(ByteOrder.nativeOrder()) .asFloatBuffer() vertexData.put(vertices) vertexData.position(0) gl.glVertexAttribPointer(aPositionLocation, POSITION_ELEMENT_COUNT, gl.GL_FLOAT, false, 0, vertexData) gl.glEnableVertexAttribArray(aPositionLocation) // draw triangle gl.glClear(gl.GL_COLOR_BUFFER_BIT) gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, POINT_COUNT)效果: 代码解释
代码和前一篇文章基本上类似,唯一的区别是顶点数据的定义:
def POSITION_ELEMENT_COUNT = 4 def vertices = [ // triangle fan // x y z w -0.5f, -0.5f, 0, 1, -0.5f, 0.5f, 0, 2, 0.5f, 0.5f, 0, 2, 0.5f, -0.5f, 0, 1, ] as float[]顶点坐标有原来的x和y扩充为xyzw,z坐标为0。靠上的两个顶点的w值为2,因此看起来更远一些。靠下的两个顶点的w值为1,所以看起来更近一些。