IPhone入门开发实例——计算器

1.创建一个新项目,选择“View-based Application”。输入名字“Cal”,这时会有如下界面。

2.选择Resources->CalViewController.xib并双击,便打开了资源编辑对话框。

3.我们会看到几个窗口。其中有一个上面写着Library,这里面全是控件。如果没有显示的话,就在最上面的“TOOLS”里单击一下就出来了。还有一个标题为“View”,这个就是视图了,在这里面加上控件,运行时就可以显示出来了。还有一个标题为“Attributes”,这个很明显的是属性,关于某个控件的属性就在这里面设置。

4.我们这次主要用的是两个控件。如下图:

上面的是按钮,下面的是一个文本框。按钮是用来负责单击123那些的,文本框是用来显示的。

5.拖动控件到View的合适位置,具体怎么拖动是你自己的事,我的结果如下图:

这里也有一个小技巧,这里有很多按钮,一个一个拖动是很麻烦的,这时,拖动一个后,选中它,按住Option(alt)键,直接拖动就可以出现一个副本,弄好上面一排后,选中一排四个,再向下拖动,就可以一下出现4个。

6.下面我们给按钮添加文字。方法是,先选中文字,然后在属性窗口里,找到Title项,在里面写上名字,最后点一下回车键。如图:

把其他的都添加好,我的结果是这样的:

7.设置文本框的属性,按下图设置:

因为计算器默认会显示一个0

8.我们要添加代码了。

  1)在CaleViewController.h里,修改代码成如下形式:

@interface CaleViewController : UIViewController {

  UITextField* txtResult;//用来表示输出口的,和TextField类型一致

}

@property(nonatomic, retain) IBOutlet UITextField* txtResult;//表示这是一个输出口

-(IBAction)ButtonPressed:(id)sender;//这是一个事件的操作部分的声明

@end

  2)在CaleViewController.m文件里按如下修改:

#import "CaleViewController.h"

 

@implementation CaleViewController

@synthesize txtResult;//通知编译器为我们创建访问方法和修改方法

上面的是在文件最上面,然后添加函数:

-(IBAction)ButtonPressed:(id)sender{

    

}

只要在@end之前就行。这是一个空函数,现在我们还没有写到功能部分。

- (void)dealloc {}函数里加上一句,当然应该在它原有的那句之前了,[txtResult release];

这是释放内存。因为IPHONE的机身内存有限,不可能像平时用电脑一样,所以一定要记得释放内存。而且由于都是指针操作,释放内存要注意,有时候就会释放错了,要多多理解指针。

9.下面要进行的是连接,只有把输入输出口连接起来,才能实现交互操作。所以,我们要把控件和表示控件的变量,操作的函数等连接起来。

具体操作如下:

连接UITextField* txtResult;和文本框控件,在控件操作程序下,按住键盘上的“CTRL”键,再单击并拖动,会出现一条蓝色的线,拖动到VIEW里的文本框控件上松开鼠标,会弹出小下拉菜单,里面就有一个txtResult,如果没有的话,检查你的定义和声明,看看类型是否一致等。再单击一下txtResult就可以了。这就连接上了。这时我们有了一个输出口,就是说以后txtResult变量就是文本框的内容。

连接按钮和操作。有两种方法,方法一:在按钮上单击右键,在对应的事件的右边圆圈里单击并拖动到上,松开就可以了。如图:

方法二:先单击按钮,然后在属性窗口里,找到如图所示:

单击ButtonPressed后面的那个小圆圈(有可能里面有黑点,没事的,正常现象),拖动到对应的按钮上松手,选择相应的事件就OK了。

最后说,我们选择的是Touch Up Inside事件,至于原因,参考《IPhone3开发基础教程》第38页。

我们把所有的按钮都添加上同一个事件,这样就使我们的接口减少了很多。

想试试都管用吗?很简单,在ButtonPressed函数里添加如下代码就可以了。

NSString* strInput = [sender titleForState:UIControlStateNormal];

  txtResult.text=strInput;

它的功能是改变文本框的内容为按钮上的字。试试吧。

当然,做完这一切,千万不要忘了保存。

10.现在就是写计算器主程序的时候了,我们的数字不能太大,Double的才能支持到多少位啊,所以要考虑的问题很多。

现在要开始真正的编程了。

好吧,我们现在来添加一个成员变量,用来表示当前屏幕上显示的数字。double displayNum;并且在viewDidLoad事件中初始化为0.0

然后我们来给按钮添加tag,数字上1就是1,然后我的列表是如下的,你自己要记住自己是怎么添加的。

09-----------09; ------10 +-×/---------1114 =---------15; 平方------16;正负--------17CE--------18

当然,这样写是我的个人习惯,您们可以把数字连接一个事件,加减连接一个,我就不在这里说了。

先说一下,这个是我的制作过程记录,以后会出现修改,这是很正常的,做程序肯定是会经常修改的。我把写错的地方也记录下来是为了让大家(尤其是初学者)来看清楚制作过程,制作过程永远不会一帆风顺。

添加一个成员函数,记住,要添加声明和定义两部分。

(double)NumPress:(int)Num;//我们用它来处理按下数字的操作

变量入口是按下的数字,返回值是目前这个数字是什么。

这个函数里先添加一句 displayNum = displayNum*10 + num;//修改显示的数字

貌似就结束了。但是这肯定是不正确的。

比如我们还要处理点和加减等操作。

我们把这个操作放到按钮的单击事件里。

代码如下:

-(IBAction)ButtonPressed:(id)sender{

     //UIButton* btn = (UIButton*)sender;//用变量指向指令发送者

     int num = [sender tag];//获取tag

     switch (num) {

            case 0:case 1:case 2:

            case 3:case 4:case 5:

            case 6:case 7:case 8:

            case 9://这部分是处理数字输入的

                   [self NumPress: num];

                   break;

            default:

                   break;

     }

}

我们先来处理小数点被按下时。先添加一个成员变量,指示小数点是否被按下。BOOL IsDotPressed;并在viewDidLoad里将其初始化为NO

添加函数,(void)DotPress{IsDotPressed = YES;}

这样的话,我们的数字按下事件就又要有变化了。

-(void)NumPress:(int)num{

     if (IsDotPressed) {

            ++afterDotNum;//先让按下的小数点后的位数加1

            displayNum = displayNum + pow((double)0.1,afterDotNum)*num;

     }

     else {

            displayNum = displayNum*10 + num;//修改显示的数字

     }

}

我们当然要让它能显示出来,否则也无法测试,不过,控件只能显示NSSTring*类型,所以要转换一下。

用以下函数,添加进去。

- (NSString *)changeFloat:(double)Right

{  

     NSString *stringFloat;

     stringFloat = [NSString stringWithFormat:@"% .10f ",Right];

     const char *floatChars = [stringFloat UTF8String];

    NSUInteger length = [stringFloat length];

     int i;

    for( i = length-1; i>=0; i--)

    {

        if(floatChars[i] == '0')

                   ;

            else

            {

            if(floatChars[i] == '.')

                i--;

            break;

        }

    }

    NSString *returnString;

    if(i == -1)

        returnString = @"0";

     else

        returnString = [stringFloat substringToIndex:i+1];

    return returnString;

}

然后我们就要调用了,在按钮单击事件里的switch的数字处理中,添加如下代码:

[txtResult setText:[self changeFloat:displayNum]];

这样就可以调用了,不过,我们发现按下点后,点却并不出现,直到再按下一个数字时,点才会出现,这显然不是我们想要的。所以,要修改处理点按下的操作。

改成如下状态:

-(void)DotPress{

     if(IsDotPressed == NO)

     {

            [txtResult setText:[NSString stringWithFormat:@"%@%@", [txtResult text], @"."]];//这里是格式化字符串,在字符串后面添加个点

            IsDotPressed = YES;

     }

}

这样就OK了。

还有一点,就是数字长度问题,数字不能无限大,所以要添加一个判定条件,在数字按下的函数最前面添加以下代码:

//长度大于等于9位时,不再操作了

     if ([txtResult.text length] >= 9 ) {

            return;

     }

下面是操作符号和等于的做法了,先说符号的。

先回忆一下计算器的工作流程,输入第一个数字,输入符号,输入第二个数,等于。这是一般的情况。我们先按一般情况来做。

添加两个函数,一个负责处理符号,一个负责等于。

-(void)OperPress:(int)oper{

     WhichOperPressed = oper-10;

     preInputNum = displayNum;

}

WhichOperPressed这个是int类型的成员变量,用来记录是哪个符号的,其中0-无,1-加,2-减,3-乘,4-除。

然后是等于的操作函数。

-(void)EquPress{

     switch (WhichOperPressed) {

            case 1://

                   displayNum += preInputNum;

                   break;

            case 2://

                   displayNum = preInputNum-displayNum;

                   break;

            case 3://

                   displayNum *= preInputNum;

                   break;

            case 4://

                   if (displayNum==0) {

                          [txtResult setText:@"除数不能为0"];

                          return;

                   }

                   else {

                          displayNum = preInputNum/displayNum;

                   }

                   break;

            default:

                   break;

     }

     [self init];

     [txtResult setText:[self changeFloat:displayNum]];

}

嗯,init也是一个函数,主要是清除工作,也可以说是初始化工作。代码如下:

-(void)init{

     preInputNum = 0.0;

     IsNumPressed=NO;

     WhichOperPressed=0;

     IsDotPressed=NO;

     afterDotNum=0;

     IsCaled=YES;

}

一般情况就是这样的,但是,我们有时会有这样的情况,输入数字,按了加号,但是发现按错了,于是按减号再输入第二个数字,再等于。这是一种,还有一种,我们输入第一个数字,按加,输入第二个数字,按加(此时应该显示的是前面两个数字的和),再输入第三个数字,等等。

所以有必要修改一下代码。

将操作符的代码做如下修改:

-(void)OperPress:(int)oper{

     if (IsNumPressed) {

            //计算结果

            [self EquPress];

     }

     WhichOperPressed = oper-10;

     preInputNum = displayNum;

     IsNumPressed=NO;

     IsCaled=NO;

     IsDotPressed=NO;

}

其中IsNumPressedBOOL类型的成员变量,初始化为NO,用来表示是否有数字按下,这是处理这两种特殊情况的。

IsCaledBOOL类型的成员变量,初始化为NO,这个的用处不在此处,而是要在NumPress函数里,修改一下代码:

-(void)NumPress:(int)num{

     IsNumPressed = YES;

     //如果有操作符号按下,则将显示的先归0

     if (WhichOperPressed!=0 || IsCaled) {

            displayNum = 0;

            [txtResult setText:[self changeFloat:displayNum]];

     }……

下面的代码都一样,就不粘了,这里主要是为了在按了等于后,再次按数字,会使数字从0开始,否则按了等于后,再按数字就在数字后面继续添加数字了。

然后是平方的运算,按了平方后的做法,特别简单,就不用再添加成员函数了,就在btnPressswitch里添加就行了,添加如下代码:

            case 16://平方

                   displayNum*=displayNum;

                   [txtResult setText:[self changeFloat:(displayNum)]];

                   [self init];

                   break;

然后该正负的按钮了。正负的出现很简单,在上面的后面再加一句:

            case 17:

                   displayNum = 0-displayNum;

                   [txtResult setText:[self changeFloat:(displayNum)]];

                   break;

是不是很简单?不过,你可以试验一下,如果现在你按了3,再按正负,再按6,出现的不是-36而是-24,这是为什么呢?因为前面我们是加的-30+6当然是-24了。

所以,NumPress函数又要修改了。

。。。。。。

//长度大于等于9位时,不再操作了

     if ([txtResult.text length] >= 9 ) {

            return;

     }

//添加的是如下部分

     if (displayNum<0) {//主要负责按了正负号后

            num = 0-num;

     }

/添加的是以上部分

     if (IsDotPressed) {

            ++afterDotNum;//先让按下的小数点后的位数加1

            displayNum = displayNum + pow((double)0.1,afterDotNum)*num;

     }

…...

其他的部分相同,就省略了。

下面是CE按钮了,这个是清除用的,用我们的init就差不多了,在BtnPress里添加如下代码:

            case 18://CE

                   [self init];

                   displayNum=0;

                   [txtResult setText:@"0"];

                   break;

现在,一个基本的计算器就完成了,我们还要测试一下,打开后,输入0.8,按+再按点,怎么了,是不是出现了“0.8.”呢?这显然有问题,修改吧,肯定是点处理的错,回想一下,点操作只是判断了一下以前有没有输入过点,而无论是符号的,还是等号的,都把其归为NO了,所以出现是很正常的,因此,我们修改成以下代码:

-(void)DotPress{

     //如果有操作符号按下,则将显示的先归0

     if (WhichOperPressed!=0 || IsCaled) {

            displayNum = 0;

            [txtResult setText:[self changeFloat:displayNum]];

     }

     if(IsDotPressed == NO)

     {

            [txtResult setText:[NSString stringWithFormat:@"%@%@", [txtResult text], @"."]];

            IsDotPressed = YES;

     }

     IsNumPressed=YES;

     IsCaled=NO;

}

因为如果有操作符按下后,按点时就相当于按了0和点,所以这样就没问题了。再试试除个0,怎么样,提示出现了吧,再按任意的数字键呢?怎么?没问题?多点几个试试 ,问题有了没?就是只能显示一位数了。这可如何是好呢?在EquPress函数里,找到以下地方:

case 4://

                   if (displayNum==0) {

                          [txtResult setText:@"除数不能为0"];

                          [self init];//在这添加一句就OK

                          return;

                   }

我们只要在上面注释的地方添加一句就OK了。大家去想想原因吧。到此,一个简单的计算器就做好了,基本功能全都有了。像界面什么的,自己去动脑子吧。

写在最后:这个功能很简单,目的只是为了将初学者引进门。因为乍一遇到XCODE这样的编译器,有很多人会很不习惯,而且会感觉无从下手。其实IPHONE编程还是很简单的,大家稍微用点心,练习一下,手熟点就没有任何问题的。关键还有就是XCODE是全英文的,有很多人会用起来别扭。以后也许会继续有一些简单的教程。大家有什么意见或者建议尽管告诉我啊,一起进步。

我邮箱:yjn234@gmail.com

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值