IOS开发入门(3)

承接上一节

简单介绍一下属性的另外两个特性:
首先,在创建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标签IBOutlettotalCarsLabel
Car NUmber标签IBOutletCarNumberLabel
Car Info标签IBOutletCarInfoLabel
New Car按钮IBActionnewCar:
Previous Car按钮IBActionpreviousCar:
Next Car按钮IBActionnextCar:

方法如图

这里写图片描述

这里写图片描述

拉过去后会跳出,对于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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值