偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

在iOS平臺(tái)上開發(fā)猜數(shù)游戲

移動(dòng)開發(fā) iOS 移動(dòng)應(yīng)用
本文將把《猜數(shù)游戲》作為例子,為大家講述在iOS平臺(tái)上開發(fā)猜數(shù)游戲。裁判從1到100以內(nèi)隨機(jī)選擇一個(gè)整數(shù),然后讓玩家猜測選擇的是什么數(shù)。每次猜測后,如果猜錯(cuò)了,裁判會(huì)告訴玩家是猜大了還是猜小了,直到玩家猜出來。大家可以看看作者代碼如何。

這些天終于戒掉了星際爭霸2,開始學(xué)習(xí)iOS開發(fā)了。雖然還只是一知半解,但學(xué)了幾天后,覺得單視圖的iOS應(yīng)用開發(fā)起來太輕松了,就忍不住想自己動(dòng)手做點(diǎn)小玩意。

我也沒有什么好的創(chuàng)意,只是偶然看到猜數(shù)的游戲,覺得用選取器這個(gè)控件很適合,就決定做了。

雖然這個(gè)游戲大多數(shù)人都玩過,不過我還是介紹下規(guī)則吧:裁判從1到100以內(nèi)隨機(jī)選擇一個(gè)整數(shù),然后讓玩家猜測選擇的是什么數(shù)。每次猜測后,如果猜錯(cuò)了,裁判會(huì)告訴玩家是猜大了還是猜小了,直到玩家猜出來。當(dāng)然,用的次數(shù)越少就越好。如果用二分法的話,7次以內(nèi)肯定能猜出來的。

而我要做的這個(gè)游戲中,裁判將由應(yīng)用本身來擔(dān)當(dāng)。玩家只要在選取器里選定一個(gè)數(shù),然后點(diǎn)擊選擇按鈕,就會(huì)得知猜測的情況;同時(shí)選取器也自動(dòng)更新,刪除不符合的數(shù)據(jù),避免玩家選擇錯(cuò)誤的數(shù)據(jù)。

接下來考慮界面。

它需要一個(gè)選取器來選數(shù),需要一個(gè)選擇按鈕來確定所選的數(shù),還需要一個(gè)重玩按鈕來重置游戲。而在通知方面,我覺得猜錯(cuò)時(shí)可以直接用標(biāo)簽來告知玩家,而在猜中時(shí)則彈出一個(gè)確認(rèn)對話框比較好。

于是就開工了,運(yùn)行Xcode,創(chuàng)建一個(gè)GuessNumber項(xiàng)目,在GuessNumberViewController.h里聲明控件變量。

  1. @interface GuessNumberViewController : UIViewController { 
  2.     UILabel *label; 
  3.     UIPickerView *picker; 
  4.  
  5. @property (nonatomic, retain) IBOutlet UILabel *label; 
  6. @property (nonatomic, retain) IBOutlet UIPickerView *picker; 
  7.  
  8. - (IBAction)chooseButtonPressed; 
  9. - (IBAction)resetButtonPressed; 
  10.  
  11. @end 

然后用Interface Builder畫出這樣一個(gè)界面出來,并與控件變量和行為連接起來:

再打開GuessNumberViewController.m,加上如下代碼,準(zhǔn)備工作就做完了:

  1. @implementation GuessNumberViewController 
  2.  
  3. @synthesize label; 
  4. @synthesize picker; 
  5.  
  6. - (void)viewDidUnload { 
  7.     self.label = nil; 
  8.     self.picker = nil; 
  9.  
  10. - (void)dealloc { 
  11.     [label release]; 
  12.     [picker release]; 
  13.     [super dealloc]; 
  14.  
  15. @end 

不過這個(gè)程序還只是個(gè)空殼,還得為它寫實(shí)現(xiàn)邏輯。先看UIPickerView。翻看SDK文檔,發(fā)現(xiàn)它并不能直接設(shè)置和顯示數(shù)據(jù),而是用UIPickerViewDelegate和UIPickerViewDataSource這2個(gè)協(xié)議來完成的。簡化起見,我就沒創(chuàng)建一個(gè)模型類了,而是直接讓GuessNumberViewController來實(shí)現(xiàn)了:

  1. @interface GuessNumberViewController : UIViewController 
  2. <UIPickerViewDelegate, UIPickerViewDataSource> 

UIPickerViewDelegate主要需要實(shí)現(xiàn)這2個(gè)方法中的一個(gè):

◆pickerView:titleForRow:forComponent:

◆pickerView:viewForRow:forComponent:reusingView:

前者是直接讓每行顯示一個(gè)字符串,而后者是每行顯示一個(gè)視圖,那自然是前者更方便了。

可是每行究竟要顯示什么數(shù)據(jù)呢?看上去可以用一個(gè)數(shù)組來保存現(xiàn)有的數(shù),然后直接將行號(hào)作為數(shù)組的索引來獲取即可。

可讓我詫異的是創(chuàng)建數(shù)組時(shí),居然沒有Python里range這樣方便的函數(shù),于是得自己寫個(gè)方法來實(shí)現(xiàn)了:

  1. + (NSMutableArray *)makeArrayFrom:(NSInteger)begin to:(NSInteger)end { 
  2.     NSMutableArray *array = [[[NSMutableArray alloc]initWithCapacity:end - begin + 1]autorelease]; 
  3.     for (NSInteger i = begin; i <= end; ++i) { 
  4.         [array addObject:[NSString stringWithFormat:@"%d", i]]; 
  5.     } 
  6.     return array; 

這樣的實(shí)現(xiàn)讓我很擔(dān)心性能,覺得還不如C的數(shù)組好用。而且NSMutableArray為什么是NSArray的子類啊,有可能接收到一個(gè)NSArray對象,以為它是不變的,結(jié)果使用時(shí)卻莫名其妙地變了啊!有木有!難道接收到后每次都copy一份不影響性能嗎?可這貨畢竟是標(biāo)準(zhǔn)庫里的,你得逼自己接受它…(好戲還在后頭)

考慮到這樣創(chuàng)建很成問題,于是決定事先創(chuàng)建好一個(gè)完整的數(shù)組,然后每次要用時(shí)就copy一份。便給GuessNumberViewController加上2個(gè)私有變量NSMutableArray *pickerData和NSMutableArray *totalData,并在viewDidLoad方法中初始化它們。

  1. #define MAX_NUMBER 100 
  2.  
  3. - (void)viewDidLoad { 
  4.     self.totalData = [GuessNumberViewController makeArrayFrom:1 to:MAX_NUMBER]; 
  5.     [self resetGame]; 
  6.     [super viewDidLoad]; 
  7.  
  8. - (void)resetGame { 
  9.     NSMutableArray *totalDataCopy = [totalData mutableCopy]; 
  10.     self.pickerData = totalDataCopy; 
  11.     [totalDataCopy release]; 
  12.  
  13. - (void)viewDidUnload { 
  14.     self.label = nil; 
  15.     self.picker = nil; 
  16.     self.pickerData = nil; 
  17.     self.totalData = nil; 
  18.  
  19. - (void)dealloc { 
  20.     [label release]; 
  21.     [picker release]; 
  22.     [pickerData release]; 
  23.     [totalData release]; 
  24.     [super dealloc]; 

數(shù)據(jù)準(zhǔn)備好后,就可以實(shí)現(xiàn)– pickerView:titleForRow:forComponent:了:

  1. - (NSString *)pickerView:(UIPickerView *)pickerView 
  2.            titleForRow:(NSInteger)row 
  3.           forComponent:(NSInteger)component { 
  4.     return [pickerData objectAtIndex:row]; 

再來看看UIPickerViewDataSource,這個(gè)協(xié)議也有2個(gè)方法:

◆numberOfComponentsInPickerView:

◆pickerView:numberOfRowsInComponent:

前者返回這個(gè)選擇器由幾個(gè)部分組成,這里我只需要一組即可;后者返回每個(gè)部分有多少行,其實(shí)也就是pickerData的長度而已:

  1. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 
  2.     return 1; 
  3.  
  4. - (NSInteger)pickerView:(UIPickerView *)pickerView 
  5. numberOfRowsInComponent:(NSInteger)component { 
  6.     return [pickerData count]; 

這時(shí)候NSArray又囧到我了。那個(gè)count方法說明了count不是個(gè)屬性,因此數(shù)組的長度并沒有用變量來保存。事后我也查了下,發(fā)現(xiàn)是以nil來判斷數(shù)組結(jié)尾的,這效率對長數(shù)組來說絕對是個(gè)災(zāi)難。

現(xiàn)在選擇器的邏輯已經(jīng)實(shí)現(xiàn)了,此時(shí)測試應(yīng)該可以看到一個(gè)包含1~100的選擇器了,不過游戲的邏輯還并沒實(shí)現(xiàn)。

于是再給GuessNumberViewController加上NSInteger guessedTimes和NSInteger secretNumber,分別用于保存玩家猜的數(shù)和隨機(jī)數(shù)。

接著修改resetGame的邏輯來初始化它們:

  1. - (void)resetGame { 
  2.     guessedTimes = 0; 
  3.     secretNumber = arc4random() % MAX_NUMBER + 1; 
  4.     NSMutableArray *totalDataCopy = [totalData mutableCopy]; 
  5.     self.pickerData = totalDataCopy; 
  6.     [totalDataCopy release]; 
  7.     [picker reloadComponent:0]; 

然后就是重點(diǎn)的chooseButtonPressed方法了,這個(gè)方法中需要?jiǎng)h除NSMutableArray的一部分,而且肯定是在頭或尾部刪除。查了下SDK文檔,適合這種批量刪除的方法有:

◆removeObjectsAtIndexes:

◆removeObjectsInArray:

◆removeObjectsInRange:

◆removeObjectsFromIndices:numIndices:

看上去很多是吧,別急,一個(gè)一個(gè)來看。

◆ removeObjectsAtIndexes:這個(gè)方法接收一個(gè)NSIndexSet參數(shù)。而NSIndexSet的創(chuàng)建和NSMutableArray差不多,也就是得循環(huán)生成,放棄。

◆removeObjectsInArray:就更直接了,直接接收一個(gè)NSArray參數(shù)。為了刪除一個(gè)數(shù)組的一部分而去創(chuàng)建另一個(gè)數(shù)組,有病啊?放棄。

◆removeObjectsInRange:接收一個(gè)NSRange參數(shù)。NSRange是一個(gè)結(jié)構(gòu),包括location和length這2個(gè)字段,看上去這就是我想要的。它實(shí)際上是用removeObjectAtIndex:來刪除對象的,所以自己寫循環(huán)來刪除會(huì)更快。

◆removeObjectsFromIndices:numIndices:已經(jīng)被deprecated了,放棄??紤]到自己寫循環(huán)太麻煩,所以還是將就著使用– removeObjectsInRange:了,實(shí)現(xiàn)的算法我就不解釋了:

  1. - (void)alertWithMessage:(NSString *)message { 
  2.     UIAlertView *alert = [[UIAlertView alloc] 
  3.                           initWithTitle:nil 
  4.                           message:message 
  5.                           delegate:nil 
  6.                           cancelButtonTitle:@"確定" 
  7.                           otherButtonTitles:nil]; 
  8.     [alert show]; 
  9.     [alert release]; 
  10.  
  11. - (IBAction)chooseButtonPressed { 
  12.     ++guessedTimes; 
  13.     NSInteger row = [picker selectedRowInComponent:0]; 
  14.     NSString *selected = [pickerData objectAtIndex:row]; 
  15.     NSInteger selectedNumber = [selected integerValue]; 
  16.     NSInteger cutIndex; 
  17.      
  18.     if (selectedNumber == secretNumber) { 
  19.         [self alertWithMessage:[NSString stringWithFormat:@"你猜中了!"]]; 
  20.         [self resetGame]; 
  21.     } else { 
  22.         cutIndex = [pickerData indexOfObject:[NSString stringWithFormat:@"%d", selectedNumber]]; 
  23.         if (selectedNumber > secretNumber) { 
  24.             label.text = [NSString stringWithFormat:@"第%d次猜數(shù),你猜得太大了。", guessedTimes]; 
  25.             [pickerData removeObjectsInRange:NSMakeRange(cutIndex, [pickerData count] - cutIndex)]; 
  26.         } else { 
  27.             label.text = [NSString stringWithFormat:@"第%d次猜數(shù),你猜得太小了。", guessedTimes]; 
  28.             [pickerData removeObjectsInRange:NSMakeRange(0, cutIndex + 1)]; 
  29.         } 
  30.     } 
  31.     [picker reloadComponent:0]; 

***別忘了resetButtonPressed,它只是調(diào)用resetGame方法而已:

  1. - (IBAction)resetButtonPressed { 
  2.     [self resetGame]; 

現(xiàn)在就可以開玩了,效果如下:

看上去iOS開發(fā)的確很簡單,只是Objective-C惡心了一點(diǎn)而已。

不過別高興得太早,這篇文章還沒完成一半呢。玩了一會(huì)后我就立刻感到不爽了:從100個(gè)數(shù)里找到想要選擇的數(shù)太難了。

如果把選取器拆成2個(gè)部分,分別選擇十位和個(gè)位就會(huì)方便多了。不過這樣一來就不能猜1~100了,而應(yīng)該猜0~99;MAX_NUMBER這個(gè)名字也不再合適,應(yīng)該改成TOTAL_NUMBERS。

除此之外,如果繼續(xù)用數(shù)組實(shí)現(xiàn)的話,我得保存1個(gè)十位的數(shù)組和10個(gè)個(gè)位的數(shù)組,這樣維護(hù)起來太頭疼了。好在數(shù)據(jù)和UIPickerView并沒有綁定起來,可以自己實(shí)現(xiàn)取數(shù)邏輯,所以干脆保存當(dāng)前最小和***的數(shù),然后計(jì)算出十位和個(gè)位得了。

于是再給GuessNumberViewController加上NSInteger beginNumber和NSInteger endNumber這2個(gè)私有變量,然后開始修改取數(shù)邏輯:

  1. - (NSString *)pickerView:(UIPickerView *)pickerView 
  2.              titleForRow:(NSInteger)row 
  3.             forComponent:(NSInteger)component { 
  4.     if (component == 0) { 
  5.         return [NSString stringWithFormat:@"%d", beginNumber / 10 + row]; 
  6.     } 
  7.      
  8.     if ([picker selectedRowInComponent:0] == 0) { 
  9.         return [NSString stringWithFormat:@"%d", beginNumber % 10 + row]; 
  10.     } 
  11.      
  12.     return [NSString stringWithFormat:@"%d", row]; 
  13.  } 
  14.  
  15. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 
  16.     return 2; 
  17.  
  18. - (NSInteger)pickerView:(UIPickerView *)pickerView 
  19. numberOfRowsInComponent:(NSInteger)component { 
  20.     NSInteger unitsDigitOfBeginNumber = beginNumber % 10; 
  21.     NSInteger unitsDigitOfEndNumber = endNumber % 10; 
  22.     NSInteger tenthsDigitOfBeginNumber = beginNumber / 10; 
  23.     NSInteger tenthsDigitOfEndNumber = endNumber / 10; 
  24.     NSInteger differenceBetweenTenthsDigits = tenthsDigitOfEndNumber - tenthsDigitOfBeginNumber; 
  25.     NSInteger rowOfTenthsPlace; 
  26.      
  27.     if (component == 0) { 
  28.         return differenceBetweenTenthsDigits + 1; 
  29.     } 
  30.      
  31.     rowOfTenthsPlace = [picker selectedRowInComponent:0]; 
  32.     if (rowOfTenthsPlace == 0) { 
  33.         if (differenceBetweenTenthsDigits == 0) { 
  34.             return unitsDigitOfEndNumber - unitsDigitOfBeginNumber + 1; 
  35.         } 
  36.         return 10 - unitsDigitOfBeginNumber; 
  37.     } 
  38.      
  39.     if (rowOfTenthsPlace == differenceBetweenTenthsDigits) { 
  40.         return unitsDigitOfEndNumber + 1; 
  41.     } 
  42.      
  43.     return 10; 

這里的邏輯比剛才復(fù)雜多了,不過慢慢看應(yīng)該能看懂的,我也就不解釋了。接下來就是chooseButtonPressed的邏輯了,這次它只要更改beginNumber和endNumber,不需要維護(hù)數(shù)組了。

  1. - (IBAction)chooseButtonPressed { 
  2.     ++guessedTimes; 
  3.      
  4.     NSInteger tenthsPlaceRow = [picker selectedRowInComponent:0]; 
  5.     NSInteger unitsPlaceRow = [picker selectedRowInComponent:1]; 
  6.      
  7.     NSString *tenthsDigitString = [self pickerView:picker titleForRow:tenthsPlaceRow forComponent:0]; 
  8.     NSString *unitsDigitString = [self pickerView:picker titleForRow:unitsPlaceRow forComponent:1]; 
  9.      
  10.     NSInteger tenthsDigit = [tenthsDigitString integerValue]; 
  11.     NSInteger unitsDigit = [unitsDigitString integerValue]; 
  12.      
  13.     NSInteger selectedNumber = tenthsDigit * 10 + unitsDigit; 
  14.      
  15.     if (selectedNumber == secretNumber) { 
  16.         [self alertWithMessage:[NSString stringWithFormat:@"你猜中了!"]]; 
  17.         [self resetGame]; 
  18.     } else if (selectedNumber > secretNumber) { 
  19.         statusLabel.text = [NSString stringWithFormat:@"第%d次猜數(shù),你猜得太大了。", guessedTimes]; 
  20.         endNumber = selectedNumber - 1; 
  21.     } else { 
  22.         statusLabel.text = [NSString stringWithFormat:@"第%d次猜數(shù),你猜得太小了。", guessedTimes]; 
  23.         beginNumber = selectedNumber + 1; 
  24.     } 
  25.     [picker reloadAllComponents]; 

而重置的代碼也得改改:

  1. - (void)resetGame { 
  2.     guessedTimes = 0; 
  3.     secretNumber = arc4random() % TOTAL_NUMBERS; 
  4.     beginNumber = 0; 
  5.     endNumber = TOTAL_NUMBERS - 1; 
  6.     label.text = @""
  7.     [picker reloadAllComponents]; 

現(xiàn)在再運(yùn)行一下,會(huì)發(fā)現(xiàn)一堆bug。最嚴(yán)重的一個(gè)就是選擇的十位數(shù)改變時(shí),個(gè)位不會(huì)相應(yīng)地改變。好在UIPickerViewDelegate協(xié)議提供了pickerView:didSelectRow:inComponent:方法,只要在十位改變時(shí),重新載入個(gè)位的數(shù)據(jù)即可:

  1. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { 
  2.     if (component == 0) { 
  3.         [picker reloadComponent:1]; 
  4.     } 

此外就是按了選擇按鈕后,個(gè)位數(shù)有時(shí)候會(huì)超過9。調(diào)試了一番后我發(fā)現(xiàn)是[picker reloadAllComponents]這行代碼的問題,它會(huì)先reload部件1,再reload部件0,而我的代碼邏輯中,部件1的數(shù)據(jù)(個(gè)位)是依賴于部件0(十位)的,于是就出錯(cuò)了。解決辦法很簡單,依次reload即可:

  1. [picker reloadComponent:0]; 
  2. [picker reloadComponent:1]; 

現(xiàn)在bug是搞定了,可是有個(gè)問題不太爽:游戲結(jié)束時(shí)彈出確認(rèn)對話框,我還沒點(diǎn)確定,游戲就已經(jīng)重置了,有點(diǎn)不符合習(xí)慣。好在UIAlertView有個(gè)delegate屬性,它的– alertView:didDismissWithButtonIndex:方法就可以延緩重置時(shí)機(jī)了。于是老辦法,給GuessNumberViewController實(shí)現(xiàn)UIAlertViewDelegate協(xié)議,然后進(jìn)行如下修改:

  1. - (void)alertWithMessage:(NSString *)message { 
  2.     UIAlertView *alert = [[UIAlertView alloc] 
  3.                           initWithTitle:nil 
  4.                           message:message 
  5.                           delegate:self 
  6.                           cancelButtonTitle:@"再玩一次" 
  7.                           otherButtonTitles:nil]; 
  8.     [alert show]; 
  9.     [alert release]; 
  10.  
  11. - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 
  12.     [self resetGame]; 

再把調(diào)用alertWithMessage下一行的[self resetGame]刪掉即可。接下來還有什么問題呢?結(jié)束時(shí)的提示太無聊了,沒動(dòng)力繼續(xù)玩下去,于是再改改chooseButtonPressed:

  1. if (selectedNumber == secretNumber) { 
  2.     if (guessedTimes < 4) { 
  3.         [self alertWithMessage:[NSString stringWithFormat:@"哼,人家才不告訴你%d次就猜中是很稀罕的呢!", guessedTimes]]; 
  4.     } else if (guessedTimes < 8) { 
  5.         [self alertWithMessage:[NSString stringWithFormat:@"別多想啦,%d次猜中是很正常的啦,繼續(xù)加油吧!", guessedTimes]]; 
  6.     } else { 
  7.         [self alertWithMessage:[NSString stringWithFormat:@"笨蛋,%d次才猜中,你有沒有用心在猜??!", guessedTimes]]; 
  8.     } 

現(xiàn)在如何呢?還有個(gè)很大的問題——數(shù)字是左對齊的,應(yīng)該弄成居中對齊的啊!可是翻了一遍文檔,確實(shí)沒找到哪里可以設(shè)置對齊屬性。在網(wǎng)上搜了一陣,發(fā)現(xiàn)需要自己創(chuàng)建UILabel作為每行的視圖,然后設(shè)置UILabel的對齊屬性:

  1. - (UIView *)pickerView:(UIPickerView *)pickerView 
  2.             viewForRow:(NSInteger)row 
  3.           forComponent:(NSInteger)component 
  4.            reusingView:(UIView *)view { 
  5.     UILabel *digitLabel; 
  6.     if (view) { 
  7.         digitLabel = (PickerViewLabel *)view; 
  8.     } else { 
  9.         digitLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)] autorelease]; 
  10.     } 
  11.      
  12.     NSString *title; 
  13.     if (component == 0) { 
  14.         title = [NSString stringWithFormat:@"%d", beginNumber / 10 + row]; 
  15.     } else if ([picker selectedRowInComponent:0] == 0) { 
  16.         title = [NSString stringWithFormat:@"%d", beginNumber % 10 + row]; 
  17.     } else { 
  18.         title = [NSString stringWithFormat:@"%d", row]; 
  19.     } 
  20.  
  21.     digitLabel.text = title; 
  22.     digitLabel.textAlignment = UITextAlignmentCenter; 
  23.     return digitLabel; 

這樣一來就有很多l(xiāng)abel了,所以原來的label就改名為statusLabel以作區(qū)分吧。而chooseButtonPressed中也需要更改數(shù)值的獲取方法

  1. NSString *tenthsDigitString = ((UILabel *)[picker viewForRow:tenthsPlaceRow forComponent:0]).text; 
  2. NSString *unitsDigitString = ((UILabel *)[picker viewForRow:unitsPlaceRow forComponent:1]).text; 

改完后立刻發(fā)現(xiàn)背景不對勁,變成白色的了。于是去掉digitLabel的背景色,順便將文本設(shè)為粗體:

  1. digitLabel.backgroundColor = [UIColor clearColor]; 
  2. digitLabel.font = [UIFont boldSystemFontOfSize:24.0]; 

現(xiàn)在是否OK了呢?不,你會(huì)發(fā)現(xiàn)點(diǎn)擊一行時(shí),還會(huì)出現(xiàn)藍(lán)色的高亮背景。這現(xiàn)象是怎么產(chǎn)生的呢?原來UIPickerView是用UITableView實(shí)現(xiàn)的,而UITableCell在選中時(shí)默認(rèn)會(huì)高亮。

簡單的解決辦法就是設(shè)置digitLabel.userInteractionEnabled = YES,這樣一來digitLabel就攔截了點(diǎn)擊事件,不會(huì)傳遞給UITableCell了。

可是這個(gè)辦法仍然有問題:默認(rèn)的UIPickerView在點(diǎn)擊一行時(shí),會(huì)滾動(dòng)定位到這行;而攔截了事件后,自動(dòng)滾動(dòng)的功能也就沒了。

于是更好的辦法就是在點(diǎn)擊時(shí)獲取這個(gè)UITableCell,將它設(shè)為不高亮。然而坑爹的是UITableCell屬于私有API,SDK文檔里找不到資料,調(diào)用它的方法得使用performSelector方法。

為此需要自定義一個(gè)PickerViewLabel類:

  1. @interface PickerViewLabel : UILabel { 
  2.  
  3.  
  4. @end 
  5.  
  6. @implementation PickerViewLabel 
  7.  
  8. - (void)didMoveToSuperview { 
  9.     UIView *superview = [self superview]; 
  10.     if ([superview respondsToSelector:@selector(setShowSelection:)]) { 
  11.         [superview performSelector:@selector(setShowSelection:) withObject:NO]; 
  12.     } 
  13.  
  14. @end 

這個(gè)didMoveToSuperview方法的名字很囧,它其實(shí)是在父視圖改變時(shí)被調(diào)用的。

因?yàn)楦吡烈彩歉淖兊囊环N,所以它就會(huì)被調(diào)用了。拿到父視圖后并不能判斷它是否是UITableCell類的對象,因?yàn)槲覀儧]有UITableCell的聲明頭文件。于是通過respondsToSelector判斷它是否能調(diào)用setShowSelection:,再通過performSelector調(diào)用這個(gè)方法。

現(xiàn)在總該可以了吧?不,還有個(gè)問題:重新載入U(xiǎn)IPickerView的組件時(shí),有時(shí)會(huì)停在莫名其妙的一行上。于是在resetGame的末尾加上:

  1. [picker selectRow:0 inComponent:0 animated:NO]; 
  2. [picker selectRow:0 inComponent:1 animated:NO]; 

同時(shí)也加在chooseButtonPressed的第三種里:

  1. // ... 
  2. else { 
  3.     statusLabel.text = [NSString stringWithFormat:@"第%d次猜數(shù),你猜得太小了。", guessedTimes]; 
  4.     beginNumber = selectedNumber + 1; 
  5.     [picker selectRow:0 inComponent:0 animated:NO]; 
  6.     [picker selectRow:0 inComponent:1 animated:NO]; 

好了,最終效果如下:

雖然按鈕的樣式還能改改,不過必須用到背景圖,我就懶得找圖了。至于還能改進(jìn)的地方,我覺得就是太不耐玩了。如果加入聯(lián)機(jī)對戰(zhàn)模式或許就大不一樣了,2個(gè)玩家可以比拼誰先猜出來,就可以獲得更多樂趣了。當(dāng)然,這玩意犯不著搞那么復(fù)雜的東東出來,反正也就自己做著玩而已。***想說的是,iOS開發(fā)難在細(xì)節(jié)。它看上去很簡單,但很多細(xì)枝末節(jié)的方面若想精益求精,就不得不耗費(fèi)苦心。一是標(biāo)準(zhǔn)庫并不好用,二是SDK設(shè)計(jì)得并不周到,三是你不得不用到私有API。

 

責(zé)任編輯:佚名 來源: keakon的涂鴉館
相關(guān)推薦

2011-03-25 14:41:52

MMO游戲iOS

2017-03-20 17:20:35

iOSTensorFlow

2022-01-21 10:35:03

Windows 11微軟安卓

2010-06-09 17:46:53

2012-07-10 13:17:33

iOS收入

2011-12-12 13:58:11

TinyCoiOSAndroid

2013-08-27 10:31:05

Headless模式Java SE設(shè)計(jì)模式

2010-05-19 16:53:31

MySQL代碼

2012-04-25 14:27:03

JavaScala

2015-03-24 19:48:24

2011-04-08 09:13:13

游戲跨平臺(tái)iOS

2017-01-12 14:26:12

青雀開發(fā)小程序

2019-06-19 16:05:51

AppImageFlathubLinux

2020-02-18 09:45:44

云計(jì)算云平臺(tái)IT

2011-08-23 09:16:19

Python

2012-04-25 14:12:12

JavaScala

2013-03-04 09:51:35

2013-08-01 10:28:52

移動(dòng)通訊應(yīng)用KikHTML5游戲

2013-12-10 09:39:01

Windows平臺(tái)Linux開發(fā)

2023-02-23 14:30:27

游戲Tcl
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)