IOS开发入门(3)
来源:互联网 发布:淘宝卖家回复模板 编辑:程序博客网 时间:2024/05/20 21:22
承接上一节
简单介绍一下属性的另外两个特性:
首先,在创建make时
@property NSString *make;
默认的是读写形式
我们可能不希望汽车对象创建后能够修改make、model或year,这时候我们可以在声明属性的时候将其声明为只读属性
方法很简单
@property (readonly) NSString *make;
这样就声明完成了,之后当我们在ViewController.m文件中试图对创建完成的myCar或者是othercar对象,试图修改其make值的时候,
系统会报错
属性声明的一般形式如下:
@property <(qualifier1,qualifier2,...)> <type> <property_name>
另外,如果我们希望实现这些属性在外部只读,而在内部可以读写。也很简单,因为可以在.m文件中重新声明属性。可以通过在Car.m文件的
@implementation语句之前增加如下代码,添加或覆盖类的接口定义:
@interface Car()@property (readwrite) int year;@property NSString *make;@property NSString *model;@end
Car对象会使用新的实例变量定义。注意明确指定readwrite并不是必须的,默认值是readwrite。所以上面代码中make与model跟year是一样的,重定义后变成内部可读写。
Objective-C的语法之类的就不再多说了
现在介绍故事面板
(来自书上)对于用户来说,界面就是我们的应用程序。它是用户与为应用程序提供动力的功能(即逻辑和数据)之间的主要门户。通过创建一些信息型和实用性元素,包括屏幕和这些屏幕上所显示的内容,可以设计与实现用户体验。我们所设计的每个屏幕可以实现如下功能:
- 显示信息,如CarValet应用程序中汽车对象的数量
- 支持动作,如通过触摸按钮创建一辆新汽车
- 请求输入,如制定汽车的品牌
- 显示用户活动的结果,其方式包括更新所展示的汽车,或者切换至一个支持用户编辑汽车的屏幕
用户每次使用应用程序时,就像是在体验故事。故事所关注的内容可能是生活管理(Calender应用程序);与朋友联系(邮件、社交应用程序等)
根据我们一开始写的Carvalet项目,我们为他搭建场景
到这个地方来
改成——Headline
其余的改变:
运行如图:(PS:New Car一开始我弄成Label,应该是Button,上面图截得New Car颜色应该与Previous,Next颜色一样,这里我就不换图了)
好了,到目前为止,我们的界面做出来了,但是只有外表,内在啥也没有,我们现在来添加的这些元素行为
添加action和outlet
方法如图
拉过去后会跳出,对于label选择Connection方式为Outlet,Name根据上表
weak表示对象的所有权,能够帮助编译器添加内存管理代码。理解这些内存限定符的意义非常重要。
button也是用同样的方法拉过去,不过跳出的对话框中要改成下图样式,Name根据上表
这是添加完6个元素后
你会发现在ViewController.m里面,自动多出了点东西,那些是按钮时间,每个按钮如何操作都在相对应的按钮方法里面实现
对于内存的介绍的话本文不多介绍,想了解更多自行谷歌(在这里推荐一个翻墙的东东,Star VPN,可以在App Store里面下载)
在ViewController.m
@implementation ViewController { NSMutableArray *arrayOfCars; //使用mutable array记录所有汽车对象 NSInteger displayedCarIndex; //指定靠下位置显示的汽车的数组索引}- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. arrayOfCars = [[NSMutableArray alloc] init];//初始化汽车的数组为空数组 displayedCarIndex = 0;//显示创建的第一辆汽车}
好了现在有保存新车的地方了,还需要创建它们,创建的方法是newCar:
newCar:方法
- (IBAction)newCar:(id)sender { Car *newCar = [[Car alloc] init];//用默认值创建新的Car对象,并将其添加到数组中 [arrayOfCars addObject:newCar];//添加 NSString *totalCarText; totalCarText = [NSString stringWithFormat:@"Total Cars: %d",[arrayOfCars count]];//基于当前的汽车数量,创建新的total Car Text字符串 self.totalCarsLabel.text = totalCarText;//更新显示泊车员字符串}
运行一下,点击new Car
这里我们会注意到,之前是999,我们只要到故事面板把他改成0就行了
加入显示汽车行为
显示对象的信息是另一种常见的任务。UILabel能显示字符串,通过界面中的text属性,可以使用任何字体、大小以及指定颜色。当text属性有所更改时,标签也会更新。
使用UILabel显示变化的信息需要4样东西:标签、标签的关联、用于显示的字符串以及设置标签文本的代码。
我们已经在场景中添加好汽车的信息标签,也已经关联到标签上。要添加对汽车的描述有几种方法:一种是通过添加公共方法,另一种是使用read-only属性和自定义的getter方法。要实现该属性和getter方法,可以参照以下步骤:
- 在Car.h文件中,在fuelAmount的下方添加这行声明属性的代码
@property (readonlu)NSString *carInfo;
- 打开Car.m文件,在initWithMake:的下方添加实现自定义getter方法的代码
- (NSString *)carInfo { return [NSString stringWithFormat: @"Car Info\n Make: %@\n Model: %@\n year: %d",self.make ? self.make :@"Unknown Make",self.model ? self.model :@"Unknown Model",self.year];}
PS 三元运算符?,不懂自行谷歌
现在,可以获得描述汽车信息的字符串,还需要一种方法,用于更新显示汽车数量和信息的标签的文本内容。可以一一设置每个标签所要更新的信息。但是,更新显示的汽车信息这种行为会在多个地方发生。在这种情况下,抽出相关的代码是良好的设计方式
在newCar:方法的上端,添加displayCurrentCarInfos方法
- (void)displayCurrentCarInfo { Car *currentCar; currentCar = [arrayOfCars objectAtIndex:displayedCarIndex]; //对当前显示的汽车对象进行加载。注意生产代码应该核对displayedCarIndex是否为有效索引 self.CarInfoLabel.text = currentCar.carInfo; //通过carInfo属性获得汽车的描述信息 NSString *carIndexText; //更新汽车的标签,注意将当前索引加1(数组从0开始) carIndexText = [NSString stringWithFormat:@"Car Number: %d",displayedCarIndex +1]; self.CarNumberLabel.text = carIndexText;}
在newCar:方法中,调用displayCurrentCarInfo
- (IBAction)newCar:(id)sender { Car *newCar = [[Car alloc] init];//用默认值创建新的Car对象,并将其添加到数组中 [arrayOfCars addObject:newCar];//添加 NSString *totalCarText; totalCarText = [NSString stringWithFormat:@"Total Cars: %d",[arrayOfCars count]];//基于当前的汽车数量,创建新的total Car Text字符串 [self dispalyCurrentCarInfo]; self.totalCarsLabel.text = totalCarText;//更新显示泊车员字符串}
运行结果
发现只有”Car Info”只有一行,这是因为我们在创建Car Information时,只弄了一行
在故事面板中如下修改(就是拉长拉宽了)
再次运行
现在操作上一辆跟下一辆
在这里先写一个changeDisplayedCar(用来令车信息改变)
因为上一辆下一辆的实质上是改变当前显示的信息
- (void)changeDisplayedCar:(NSInteger)newIndex { if(newIndex < 0) { //确保新的索引值是有效的索引。如果索引小于0,使值为0 newIndex = 0; } else if(newIndex >= [arrayOfCars count]) {//如果newIndex超出arrayOfCar的范围,就将其设置为最后一个 newIndex = [arrayOfCars count] - 1; } if (displayedCarIndex != newIndex) {//仅更新索引值有变化的视图 displayedCarIndex = newIndex; [self displayCurrentCarInfo]; }}
previousCar:和nextCar:方法如下
- (IBAction)previousCar:(id)sender { [self changeDisplayedCar:displayedCarIndex - 1];}- (IBAction)nextCar:(id)sender { [self changeDisplayedCar:displayedCarIndex + 1];}
运行结果
- (void)updateLabel:(UILabel*)theLabel withBaseString:(NSString*)baseString count:(NSInteger)theCount { NSString *nexText; nexText = [NSString stringWithFormat:@"%@: %d",baseString,theCount]; theLabel.text = nexText;}
下面这些代码是让newCar和显示车辆信息通过一个专门的更新标签的方法来实现标签的更新,这样就不用每一个标签写一个专门的更改的方法了
- (void)displayCurrentCarInfo { Car *currentCar; currentCar = [arrayOfCars objectAtIndex:displayedCarIndex]; //对当前显示的汽车对象进行加载。注意生产代码应该核对displayedCarIndex是否为有效索引 self.CarInfoLabel.text = currentCar.carInfo; //通过carInfo属性获得汽车的描述信息 [self updateLabel:self.CarNumberLabel withBaseString:@"Car Number" count:displayedCarIndex +1];}- (IBAction)newCar:(id)sender { Car *newCar = [[Car alloc] init];//用默认值创建新的Car对象,并将其添加到数组中 [arrayOfCars addObject:newCar];//添加 [self updateLabel:self.totalCarsLabel withBaseString:@"Total Cars" count:[arrayOfCars count]];}
今天的介绍就到这里咯
我的另一个博客站点:Arnold-你们好啊
- IOS开发入门(3)
- IOS开发入门(1)
- IOS开发入门(2)
- IOS开发入门(4)
- IOS开发入门(5)
- ios开发(二十)入门图表
- iOS开发入门(好东西)
- IOS开发入门(10)-滚动
- iOS 8开发入门--序言(1)
- iOS 8开发入门--序言(2)
- iOS 8开发入门--序言(2)
- iOS 8开发入门--序言(2)
- ios 开发入门资料
- IOS开发入门
- 【iOS开发】---- ARC 入门
- ios 入门开发三
- 第一章 ios开发入门
- iOS开发~OPenCV入门
- Hadoop浅学习&实践学习——初级2.0[真实分布集群]
- tensorflow入门(一)---从一个小程序说起
- Linux内核——遍历 net_device 结构
- Graphite 系统安装
- Win7,64位下Python3.5.2,安装numpy、matplotlib、scipy(whl文件)
- IOS开发入门(3)
- C++类构造函数初始化列表及初始化成员变量的误区
- Wechat4j之Hello world——使用wechat4j快速开发java版微信公众号
- unity获取手机联网ip
- java微信开发(wechat4j)——wechat4j配置文件解读
- 在liuger的嵌入式经历( linux android fpga dsp ipcore算法)
- Android N Audio: AudioTrack 向上通知的路径
- 设计模式——单例模式
- 解读x264_param_default 参数