Xcode做简易计算器
1.創(chuàng)建一個(gè)新項(xiàng)目,選擇“View-based Application”。輸入名字“Cal”,這時(shí)會(huì)有如下界面。
2.選擇Resources->CalViewController.xib并雙擊,便打開了資源編輯對話框。
3.我們會(huì)看到幾個(gè)窗口。其中有一個(gè)上面寫著Library,這里面全是控件。如果沒有顯示的話,就在最上面的“TOOLS”里單擊一下就出來了。還有一個(gè)標(biāo)題為“View”,這個(gè)就是視圖了,在這里面加上控件,運(yùn)行時(shí)就可以顯示出來了。還有一個(gè)標(biāo)題為“Attributes”,這個(gè)很明顯的是屬性,關(guān)于某個(gè)控件的屬性就在這里面設(shè)置。
4.我們這次主要用的是兩個(gè)控件。如下圖:
上面的是按鈕,下面的是一個(gè)文本框。按鈕是用來負(fù)責(zé)單擊123那些的,文本框是用來顯示的。
5.拖動(dòng)控件到View的合適位置,具體怎么拖動(dòng)是你自己的事,我的結(jié)果如下圖:
這里也有一個(gè)小技巧,這里有很多按鈕,一個(gè)一個(gè)拖動(dòng)是很麻煩的,這時(shí),拖動(dòng)一個(gè)后,選中它,按住Option(alt)鍵,直接拖動(dòng)就可以出現(xiàn)一個(gè)副本,弄好上面一排后,選中一排四個(gè),再向下拖動(dòng),就可以一下出現(xiàn)4個(gè)。
6.下面我們給按鈕添加文字。方法是,先選中文字,然后在屬性窗口里,找到Title項(xiàng),在里面寫上名字,最后點(diǎn)一下回車鍵。如圖:
把其他的都添加好,我的結(jié)果是這樣的:
7.設(shè)置文本框的屬性,按下圖設(shè)置:
因?yàn)橛?jì)算器默認(rèn)會(huì)顯示一個(gè)0。
8.我們要添加代碼了。
? (1)在CaleViewController.h里,修改代碼成如下形式:
@interface CaleViewController : UIViewController {
? UITextField* txtResult;//用來表示輸出口的,和TextField類型一致
}
@property(nonatomic, retain) IBOutlet UITextField* txtResult;//表示這是一個(gè)輸出口
-(IBAction)ButtonPressed:(id)sender;//這是一個(gè)事件的操作部分的聲明
@end
? (2)在CaleViewController.m文件里按如下修改:
#import "CaleViewController.h"
?
@implementation CaleViewController
@synthesize txtResult;//通知編譯器為我們創(chuàng)建訪問方法和修改方法
上面的是在文件最上面,然后添加函數(shù):
-(IBAction)ButtonPressed:(id)sender{
????
}
只要在@end之前就行。這是一個(gè)空函數(shù),現(xiàn)在我們還沒有寫到功能部分。
在- (void)dealloc {}函數(shù)里加上一句,當(dāng)然應(yīng)該在它原有的那句之前了,[txtResult release];
這是釋放內(nèi)存。因?yàn)镮PHONE的機(jī)身內(nèi)存有限,不可能像平時(shí)用電腦一樣,所以一定要記得釋放內(nèi)存。而且由于都是指針操作,釋放內(nèi)存要注意,有時(shí)候就會(huì)釋放錯(cuò)了,要多多理解指針。
9.下面要進(jìn)行的是連接,只有把輸入輸出口連接起來,才能實(shí)現(xiàn)交互操作。所以,我們要把控件和表示控件的變量,操作的函數(shù)等連接起來。
具體操作如下:
連接UITextField* txtResult;和文本框控件,在控件操作程序下,按住鍵盤上的“CTRL”鍵,再單擊并拖動(dòng),會(huì)出現(xiàn)一條藍(lán)色的線,拖動(dòng)到VIEW里的文本框控件上松開鼠標(biāo),會(huì)彈出小下拉菜單,里面就有一個(gè)txtResult,如果沒有的話,檢查你的定義和聲明,看看類型是否一致等。再單擊一下txtResult就可以了。這就連接上了。這時(shí)我們有了一個(gè)輸出口,就是說以后txtResult變量就是文本框的內(nèi)容。
連接按鈕和操作。有兩種方法,方法一:在按鈕上單擊右鍵,在對應(yīng)的事件的右邊圓圈里單擊并拖動(dòng)到上,松開就可以了。如圖:
方法二:先單擊按鈕,然后在屬性窗口里,找到如圖所示:
單擊ButtonPressed后面的那個(gè)小圓圈(有可能里面有黑點(diǎn),沒事的,正常現(xiàn)象),拖動(dòng)到對應(yīng)的按鈕上松手,選擇相應(yīng)的事件就OK了。
最后說,我們選擇的是Touch Up Inside事件,至于原因,參考《IPhone3開發(fā)基礎(chǔ)教程》第38頁。
我們把所有的按鈕都添加上同一個(gè)事件,這樣就使我們的接口減少了很多。
想試試都管用嗎?很簡單,在ButtonPressed函數(shù)里添加如下代碼就可以了。
NSString* strInput = [sender titleForState:UIControlStateNormal];
? txtResult.text=strInput;
它的功能是改變文本框的內(nèi)容為按鈕上的字。試試吧。
當(dāng)然,做完這一切,千萬不要忘了保存。
10.現(xiàn)在就是寫計(jì)算器主程序的時(shí)候了,我們的數(shù)字不能太大,Double的才能支持到多少位啊,所以要考慮的問題很多。
現(xiàn)在要開始真正的編程了。
好吧,我們現(xiàn)在來添加一個(gè)成員變量,用來表示當(dāng)前屏幕上顯示的數(shù)字。double displayNum;并且在viewDidLoad事件中初始化為0.0。
然后我們來給按鈕添加tag,數(shù)字上1就是1,然后我的列表是如下的,你自己要記住自己是怎么添加的。
0~9-----------0~9; 點(diǎn)------10; +-×/---------11~14; =---------15; 平方------16;正負(fù)--------17;CE--------18。
當(dāng)然,這樣寫是我的個(gè)人習(xí)慣,您們可以把數(shù)字連接一個(gè)事件,加減連接一個(gè),我就不在這里說了。
先說一下,這個(gè)是我的制作過程記錄,以后會(huì)出現(xiàn)修改,這是很正常的,做程序肯定是會(huì)經(jīng)常修改的。我把寫錯(cuò)的地方也記錄下來是為了讓大家(尤其是初學(xué)者)來看清楚制作過程,制作過程永遠(yuǎn)不會(huì)一帆風(fēng)順。
添加一個(gè)成員函數(shù),記住,要添加聲明和定義兩部分。
(double)NumPress:(int)Num;//我們用它來處理按下數(shù)字的操作
變量入口是按下的數(shù)字,返回值是目前這個(gè)數(shù)字是什么。
這個(gè)函數(shù)里先添加一句 displayNum = displayNum*10 + num;//修改顯示的數(shù)字
貌似就結(jié)束了。但是這肯定是不正確的。
比如我們還要處理點(diǎn)和加減等操作。
我們把這個(gè)操作放到按鈕的單擊事件里。
代碼如下:
-(IBAction)ButtonPressed:(id)sender{
???? //UIButton* btn = (UIButton*)sender;//用變量指向指令發(fā)送者
???? int num = [sender tag];//獲取tag值
???? switch (num) {
??????????? case0:case1:case2:
??????????? case3:case4:case5:
??????????? case6:case7:case8:
??????????? case9://這部分是處理數(shù)字輸入的
?????????????????? [selfNumPress: num];
?????????????????? break;
??????????? default:
?????????????????? break;
???? }
}
我們先來處理小數(shù)點(diǎn)被按下時(shí)。先添加一個(gè)成員變量,指示小數(shù)點(diǎn)是否被按下。BOOL IsDotPressed;并在viewDidLoad里將其初始化為NO。
添加函數(shù),(void)DotPress{IsDotPressed = YES;}
這樣的話,我們的數(shù)字按下事件就又要有變化了。
-(void)NumPress:(int)num{
???? if (IsDotPressed) {
??????????? ++afterDotNum;//先讓按下的小數(shù)點(diǎn)后的位數(shù)加1
??????????? displayNum = displayNum + pow((double)0.1,afterDotNum)*num;
???? }
???? else {
??????????? displayNum = displayNum*10 + num;//修改顯示的數(shù)字
???? }
}
我們當(dāng)然要讓它能顯示出來,否則也無法測試,不過,控件只能顯示NSSTring*類型,所以要轉(zhuǎn)換一下。
用以下函數(shù),添加進(jìn)去。
- (NSString *)changeFloat:(double)Right
{??
???? NSString *stringFloat;
???? stringFloat = [NSStringstringWithFormat:@"%.10f",Right];
???? constchar *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;
}
然后我們就要調(diào)用了,在按鈕單擊事件里的switch的數(shù)字處理中,添加如下代碼:
[txtResultsetText:[selfchangeFloat:displayNum]];
這樣就可以調(diào)用了,不過,我們發(fā)現(xiàn)按下點(diǎn)后,點(diǎn)卻并不出現(xiàn),直到再按下一個(gè)數(shù)字時(shí),點(diǎn)才會(huì)出現(xiàn),這顯然不是我們想要的。所以,要修改處理點(diǎn)按下的操作。
改成如下狀態(tài):
-(void)DotPress{
???? if(IsDotPressed == NO)
???? {
??????????? [txtResultsetText:[NSStringstringWithFormat:@"%@%@", [txtResulttext], @"."]];//這里是格式化字符串,在字符串后面添加個(gè)點(diǎn)
??????????? IsDotPressed = YES;
???? }
}
這樣就OK了。
還有一點(diǎn),就是數(shù)字長度問題,數(shù)字不能無限大,所以要添加一個(gè)判定條件,在數(shù)字按下的函數(shù)最前面添加以下代碼:
//長度大于等于9位時(shí),不再操作了
???? if ([txtResult.text length] >= 9 ) {
??????????? return;
???? }
下面是操作符號(hào)和等于的做法了,先說符號(hào)的。
先回憶一下計(jì)算器的工作流程,輸入第一個(gè)數(shù)字,輸入符號(hào),輸入第二個(gè)數(shù),等于。這是一般的情況。我們先按一般情況來做。
添加兩個(gè)函數(shù),一個(gè)負(fù)責(zé)處理符號(hào),一個(gè)負(fù)責(zé)等于。
-(void)OperPress:(int)oper{
???? WhichOperPressed = oper-10;
???? preInputNum = displayNum;
}
WhichOperPressed這個(gè)是int類型的成員變量,用來記錄是哪個(gè)符號(hào)的,其中0-無,1-加,2-減,3-乘,4-除。
然后是等于的操作函數(shù)。
-(void)EquPress{
???? switch (WhichOperPressed) {
??????????? case1://加
?????????????????? displayNum += preInputNum;
?????????????????? break;
??????????? case2://減
?????????????????? displayNum = preInputNum-displayNum;
?????????????????? break;
??????????? case3://乘
?????????????????? displayNum *= preInputNum;
?????????????????? break;
??????????? case4://除
?????????????????? if (displayNum==0) {
????????????????????????? [txtResultsetText:@"除數(shù)不能為0"];
????????????????????????? return;
?????????????????? }
?????????????????? else {
????????????????????????? displayNum = preInputNum/displayNum;
?????????????????? }
?????????????????? break;
??????????? default:
?????????????????? break;
???? }
???? [selfinit];
???? [txtResultsetText:[selfchangeFloat:displayNum]];
}
嗯,init也是一個(gè)函數(shù),主要是清除工作,也可以說是初始化工作。代碼如下:
-(void)init{
???? preInputNum = 0.0;
???? IsNumPressed=NO;
???? WhichOperPressed=0;
???? IsDotPressed=NO;
???? afterDotNum=0;
???? IsCaled=YES;
}
一般情況就是這樣的,但是,我們有時(shí)會(huì)有這樣的情況,輸入數(shù)字,按了加號(hào),但是發(fā)現(xiàn)按錯(cuò)了,于是按減號(hào)再輸入第二個(gè)數(shù)字,再等于。這是一種,還有一種,我們輸入第一個(gè)數(shù)字,按加,輸入第二個(gè)數(shù)字,按加(此時(shí)應(yīng)該顯示的是前面兩個(gè)數(shù)字的和),再輸入第三個(gè)數(shù)字,等等。
所以有必要修改一下代碼。
將操作符的代碼做如下修改:
-(void)OperPress:(int)oper{
???? if (IsNumPressed) {
??????????? //計(jì)算結(jié)果
??????????? [selfEquPress];
???? }
???? WhichOperPressed = oper-10;
???? preInputNum = displayNum;
???? IsNumPressed=NO;
???? IsCaled=NO;
???? IsDotPressed=NO;
}
其中IsNumPressed是BOOL類型的成員變量,初始化為NO,用來表示是否有數(shù)字按下,這是處理這兩種特殊情況的。
IsCaled是BOOL類型的成員變量,初始化為NO,這個(gè)的用處不在此處,而是要在NumPress函數(shù)里,修改一下代碼:
-(void)NumPress:(int)num{
???? IsNumPressed = YES;
???? //如果有操作符號(hào)按下,則將顯示的先歸0
???? if (WhichOperPressed!=0 || IsCaled) {
??????????? displayNum = 0;
??????????? [txtResultsetText:[selfchangeFloat:displayNum]];
???? }……
下面的代碼都一樣,就不粘了,這里主要是為了在按了等于后,再次按數(shù)字,會(huì)使數(shù)字從0開始,否則按了等于后,再按數(shù)字就在數(shù)字后面繼續(xù)添加數(shù)字了。
然后是平方的運(yùn)算,按了平方后的做法,特別簡單,就不用再添加成員函數(shù)了,就在btnPress的switch里添加就行了,添加如下代碼:
??????????? case16://平方
?????????????????? displayNum*=displayNum;
?????????????????? [txtResultsetText:[selfchangeFloat:(displayNum)]];
?????????????????? [selfinit];
?????????????????? break;
然后該正負(fù)的按鈕了。正負(fù)的出現(xiàn)很簡單,在上面的后面再加一句:
??????????? case17:
?????????????????? displayNum = 0-displayNum;
?????????????????? [txtResultsetText:[selfchangeFloat:(displayNum)]];
?????????????????? break;
是不是很簡單?不過,你可以試驗(yàn)一下,如果現(xiàn)在你按了3,再按正負(fù),再按6,出現(xiàn)的不是-36而是-24,這是為什么呢?因?yàn)榍懊嫖覀兪羌拥?30+6當(dāng)然是-24了。
所以,NumPress函數(shù)又要修改了。
。。。。。。
//長度大于等于9位時(shí),不再操作了
???? if ([txtResult.textlength] >= 9 ) {
??????????? return;
???? }
//添加的是如下部分
???? if (displayNum<0) {//主要負(fù)責(zé)按了正負(fù)號(hào)后
??????????? num = 0-num;
???? }
/添加的是以上部分
???? if (IsDotPressed) {
??????????? ++afterDotNum;//先讓按下的小數(shù)點(diǎn)后的位數(shù)加1
??????????? displayNum = displayNum + pow((double)0.1,afterDotNum)*num;
???? }
…...
其他的部分相同,就省略了。
下面是CE按鈕了,這個(gè)是清除用的,用我們的init就差不多了,在BtnPress里添加如下代碼:
??????????? case18://CE
?????????????????? [selfinit];
?????????????????? displayNum=0;
?????????????????? [txtResultsetText:@"0"];
?????????????????? break;
現(xiàn)在,一個(gè)基本的計(jì)算器就完成了,我們還要測試一下,打開后,輸入0.8,按+再按點(diǎn),怎么了,是不是出現(xiàn)了“0.8.”呢?這顯然有問題,修改吧,肯定是點(diǎn)處理的錯(cuò),回想一下,點(diǎn)操作只是判斷了一下以前有沒有輸入過點(diǎn),而無論是符號(hào)的,還是等號(hào)的,都把其歸為NO了,所以出現(xiàn)是很正常的,因此,我們修改成以下代碼:
-(void)DotPress{
???? //如果有操作符號(hào)按下,則將顯示的先歸0
???? if (WhichOperPressed!=0 || IsCaled) {
??????????? displayNum = 0;
??????????? [txtResultsetText:[selfchangeFloat:displayNum]];
???? }
???? if(IsDotPressed == NO)
???? {
??????????? [txtResultsetText:[NSStringstringWithFormat:@"%@%@", [txtResulttext], @"."]];
??????????? IsDotPressed = YES;
???? }
???? IsNumPressed=YES;
???? IsCaled=NO;
}
因?yàn)槿绻胁僮鞣聪潞?#xff0c;按點(diǎn)時(shí)就相當(dāng)于按了0和點(diǎn),所以這樣就沒問題了。再試試除個(gè)0,怎么樣,提示出現(xiàn)了吧,再按任意的數(shù)字鍵呢?怎么?沒問題?多點(diǎn)幾個(gè)試試 ,問題有了沒?就是只能顯示一位數(shù)了。這可如何是好呢?在EquPress函數(shù)里,找到以下地方:
case4://除
?????????????????? if (displayNum==0) {
????????????????????????? [txtResultsetText:@"除數(shù)不能為0"];
????????????????????????? [selfinit];//在這添加一句就OK了
????????????????????????? return;
?????????????????? }
我們只要在上面注釋的地方添加一句就OK了。大家去想想原因吧。到此,一個(gè)簡單的計(jì)算器就做好了,基本功能全都有了。像界面什么的,自己去動(dòng)腦子吧。
寫在最后:這個(gè)功能很簡單,目的只是為了將初學(xué)者引進(jìn)門。因?yàn)檎б挥龅絏CODE這樣的編譯器,有很多人會(huì)很不習(xí)慣,而且會(huì)感覺無從下手。其實(shí)IPHONE編程還是很簡單的,大家稍微用點(diǎn)心,練習(xí)一下,手熟點(diǎn)就沒有任何問題的。關(guān)鍵還有就是XCODE是全英文的,有很多人會(huì)用起來別扭。以后也許會(huì)繼續(xù)有一些簡單的教程。大家有什么意見或者建議盡管告訴我啊,一起進(jìn)步。
總結(jié)
以上是生活随笔為你收集整理的Xcode做简易计算器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: object-c 日志
- 下一篇: 的界面跳转