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

其余的改变:

可视化元素 作用 类名 Total Cars 显示停泊的汽车总数–Car对象的数量 UILabel New Car 通过添加新的Car对象,停泊一辆车 UIButton Divider 在增加汽车和查看汽车两块区域间添加一条视觉分割线,不会的话下面有图解 UIView Current Car Number 显示当前所展示的汽车对象的索引数 UILabel Car Information 显示当前汽车的详情 UILabel Previous 让泊车员浏览汽车,提供前一辆汽车的详情(如果有车) UIButton Next 提供下一辆车的详情(如果有车) UIButton

这里写图片描述

这里写图片描述

运行如图:(PS:New Car一开始我弄成Label,应该是Button,上面图截得New Car颜色应该与Previous,Next颜色一样,这里我就不换图了)

这里写图片描述

好了,到目前为止,我们的界面做出来了,但是只有外表,内在啥也没有,我们现在来添加的这些元素行为

添加action和outlet

元素 类型 名称 Total Car标签 IBOutlet totalCarsLabel Car NUmber标签 IBOutlet CarNumberLabel Car Info标签 IBOutlet CarInfoLabel New Car按钮 IBAction newCar: Previous Car按钮 IBAction previousCar: Next Car按钮 IBAction nextCar:

方法如图

这里写图片描述

这里写图片描述

拉过去后会跳出,对于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方法,可以参照以下步骤:

  1. 在Car.h文件中,在fuelAmount的下方添加这行声明属性的代码@property (readonlu)NSString *carInfo;
  2. 打开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-你们好啊

0 0
原创粉丝点击