顯示具有 程式範例 標籤的文章。 顯示所有文章
顯示具有 程式範例 標籤的文章。 顯示所有文章

2012年3月1日 星期四

NSDateFormatter設定日期格式

日期常常會因不同的需求,以不同的型態出現,在iOS雖然會依你iphone/ipad上設定的國別自動調整日期習慣的顯示方式(例如台灣格式是年/月/日,美國格式就變成月/日/年), 但是有時侯你還是有需要自已設定成需要的格式。在這裡示範樂田麵包屋裡兌換商品畫面裡2個日期的實作:


首先,先講右邊圓形郵戳的實作:


先在.h宣告一個UILabel來讓日期顯示在畫面上


IBOutlet UILabel *todayDate;//宣告一個UILabel叫todayDate

接下來在.m裡設置一個getDate這個程序來格式化這個日期

- (void)getDate{
    NSDate *date = [NSDate date]; //先取得現在的日期時間
    NSDateFormatter *form = [[NSDateFormatter alloc] init]; //宣告一個NSDateFormatter用來格式化日期
    [form setDateFormat:@"yyyy.MM.dd"]; //把日期顯示的格式設成“yyyy.MM.dd"各代表的意義請參照下面列表
    NSString *dateStr=[form stringFromDate:date]; //將格式化後的日期格式設成dateStr這個字串中
    todayDate.text = dateStr; //設定todayDate這個label的文字為dateStr這個字串的值
}

日期格式代表意義
﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣
yyyy = 年(4位數), yy = 年(最後2位數),MM = 月(1~12),MMM = 月(英文縮寫),MMMM = 月(英文完整)
K = 時(12小時制),H = 時(24小時制),mm = 分,ss = 秒,aa = 午前/午後(AM/PM)
dd = 日,EEE = 星期(英文縮寫),EEEE = 星期(英文完整)
﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣﹣

接下來說明左側的“賞味期限”的日期格式,賞味期限的日期是今天後的2天。一樣先在.h宣告一個UILabel

IBOutlet UILabel *remainDate; //宣告一個UILabel叫remainDate

接下來在.m裡設置一個getRemainDate這個程序來格式化這個日期

- (void)getRemainDate{
     NSDate *date = [NSDate date]; //一樣先取得日期的日期
   //設定一個reserveDate是今天的日期加上2天,但是NSDate都是以秒處理,所以先算出2天一共是(2*24*60*60)秒, 用dateByAddingTimeInterval把算出來的秒數加到date這個我們剛取得的現在的日期中
   NSDate *reserveDate = [date dateByAddingTimeInterval:(2*24*60*60)];
      NSDateFormatter *form = [[NSDateFormatter alloc] init];//宣告一個NSDateFormatter用來格式化日期
   [form setDateFormat:@"MM/dd"];//把日期設為月/日的格式
   remainDate.text = [NSString stringWithFormat:@"%@",[form stringFromDate:reserveDate]];//跟上面例子最後2行一樣的功能,只是縮寫成一段就是變這個樣子
}

至於右邊郵戳怎麼轉15度角,請參考UIView 同時移動、旋轉、放大的作法

2012年2月23日 星期四

鋼鐵人的HUD實作

從我開始寫APP的第一天開始,我就夢想著有一天可以做出像是關鍵報告或是鋼鐵人那種充滿未來性、科技感的操作界面,但是說實在的,也不是這麼難,這裡就來示範一下怎麼做實作出這麼酷的UI。



















首先,先要把這基本的HUD(抬頭顯示器?)畫出來,在這裡有教學網頁教怎麼用photoshop畫出類似的風格。我是沒照著那裡教的畫,直接看著上面這張電影裡的截圖畫了幾個圈示意一下。

雖然在那個教學網站裡,教你畫出這一堆圓圈後,他的工作就完成了,但是,對我們來說,不是只是要“看”起來像鋼鐵人的畫面,我們是要讓他“用”起來像鋼鐵人用的才酷。

所以,先把剛才畫的一堆圈圈拆成個別的一個一個的圈圈,我是拆成5個圈圈,分別存成5個PNG檔(如下圖)。分別命名為circle1Image到circle5Image。實作方式請看下列程式說明。











先在.h宣告如下:

//4個圈圈的UIImageView


    IBOutlet UIImageView *circle1Image;
    IBOutlet UIImageView *circle2Image;
    IBOutlet UIImageView *circle3Image;
    IBOutlet UIImageView *circle5Image;

//4個圈圈的CGAffineTransform

    CGAffineTransform circle1Transform;
    CGAffineTransform circle2Transform;
    CGAffineTransform circle3Transform;
    CGAffineTransform circle5Transform;

然後在.m實作

在initWithNibName裡先宣告一個NSTimer可以讓圈圈自已轉起來

//每0.03秒執行一次selfMoveCircle這個程序

timer =[NSTimer scheduledTimerWithTimeInterval:0.03f 
target:self
                              selector:@selector(selfMoveCircle)
      userInfo:nil
       repeats:YES];

//在這個selfMoveCircle裡只讓3個圈圈自已會一直轉,另外2個圈圈是要聽令於我們的指揮,當作操作控制的轉盤。

-(void)selfMoveCircle{
    circle5Transform = circle5Image.transform;
    circle3Transform = circle3Image.transform;
    circle2Transform = circle2Image.transform;
    //把3個圈轉動的速度設成不同,感覺比較不會這麼死板
    circle5Image.transform = CGAffineTransformRotate(circle5Transform, 0.02);
    circle3Image.transform = CGAffineTransformRotate(circle3Transform, 0.02);
    circle2Image.transform = CGAffineTransformRotate(circle2Transform, 0.04);
}

//當我們轉動轉盤的時侯,最外圍的圈circle1Image, 跟著我們轉動的方向反方向轉動。

- (void)controlCircleMove:(NSInteger)wheelCV{
    if (wheelCV >0) {
        circle1Transform = circle1Image.transform;
        circle1Image.transform = CGAffineTransformRotate(circle1Transform, -0.6);
    }else {
        circle1Transform = circle1Image.transform;
        circle1Image.transform = CGAffineTransformRotate(circle1Transform, 0.6);
    }
}

耶...怎麼沒宣告和實作到circle4Image呢?因為circle4Image是我們主要的操控盤,也就是我們手指怎麼轉,它就跟著怎麼轉,所以它是要另外再宣告在一個wheelView.h,並實作在wheelView.m負責控管我們手指的轉動方向,並把轉動的值傳回到這裡來告訴circle1Image要怎麼轉。但是實作轉輪又是一個大工程,另外再寫一篇怎麼實作好了。

2012年2月11日 星期六

Vin Gear畫面拆解

我想大部份的男生都是機械迷, 從小玩樂高,長大就迷機車、汽車,有了錢就迷相機,機械錶。對這些小零件組合起來的神奇工具從小就無法抗拒。

我也是個機械迷,所以我在設計第一個APP的時侯,最初的想法就是從機械錶開始發想的。雖然最後的成果和錶無關,但是從這個APP中不難看出機械錶對這個APP最終操作的影響。

每一個轉輪都像齒輪的連動一樣,當初我花了很多的時間在計算每個轉盤轉動的角度,然後把這些角度轉換成代表的數值。下次有時間我再來分享這些換算的方法。




2012年2月9日 星期四

用AVAudioRecorder感應聲音

這是一個還沒有完成的app, 這2年其實還有不少寫到一半就荒癈的程式,有時侯是靈感沒了,有時侯是突然有別的想法就全心投入另一件事了,有時侯是突然接到案子,有錢賺的事當然優先,所以就丟下做到一半的事。當初想寫這個app是因為我姐剛生了小baby, 我就想寫一個app是可以感應到baby的哭聲,然後就會開始放安撫小孩的音樂。因為當初我女兒小時侯有一個類似的玩具,就是小孩哭的時侯他會自已播音樂,我覺得iphone應該也能做到同樣的功能。


當初我是設計了白天模式與夜晚模式可以切換,白天模式(其實也不一定是白天用,就是手動模式)可以自已選曲,自已手動啟動,就像是個音樂盒,大人可以手動播音樂給baby聽。夜間模式就是大家都睡了的時侯,他會自動偵測是不是有baby的哭聲,如果偵測到了,就會自已播放音樂安撫baby。

怎麼去設定感應的敏感度下次再談,等一下要出門去吃喜酒,先把怎麼設感應聲音的功能分享一下,免得又忘了。

在.h先import AVFoundation

#import <AVFoundation/AVFoundation.h>

然後宣告

AVAudioRecorder *recorder;

在.m的ViewDidLoad裡init recorder

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];

設定一個NSTimer固定頻率去偵測有沒有哭聲

-(void)levelTimerCallback:(NSTimer *)timer{
[recorder updateMeters];
const double ALPHA = 0.05;
  double peakPowerForChannel = pow(10, (0.05 *[recorder peakPowerForChannel:0]));
  lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;

  if (pause = NO) {
  if (lowPassResults > senseValue) {
  NSLog(@"baby cry detected");
  [playSong play];
  playing = YES;
  [playStatus setImage:[UIImage imageNamed:@"StopIcon.png"]];
  }
  }
}

先出門了,還沒完,下次再補...sorry....

2012年2月3日 星期五

UIView 同時移動、旋轉、放大的作法

在orderGear裡有個我很喜歡的動畫效果,就是如果點選左手邊的菜色相片,它就會移動到畫面的中央並放大、轉正。
點選前:

點選後:

這裡來示範一下怎麼用setAnimation來實作這樣的效果。

先在.h宣告

IBOutlet UIView *photoframeView_4;


因為這張看似拍立得的相片中包含了相片、框、菜名、按揵等好幾個物件,所以設定為UIView來包含所有物件, 而不是用UIImageView, 如果只有一張圖的時侯還是可以用UIImageView。

然後在.m實作一個IBAction,就是當按下這張相片時的動作。

-(IBAction) showEnlargePhotoframe:(id)sender{
   CGPoint photoframe_4CurrentPOS = photoframeView_4.center;
photoframe_4CurrentPOS.x = 142; //移動前的x座標
photoframe_4CurrentPOS.y = 573; //移動前的y座標
photoframeView_4.center = photoframe_4CurrentPOS;
float angle_4  = -14*(PI/100); //原來旋轉的角度
CGAffineTransform transformRotate_4 = CGAffineTransformMakeRotation(angle_4);
CGAffineTransform transform_4 = CGAffineTransformScale(transformRotate_4, 0.36, 0.36); //原來的大小(原本尺寸縮到36%的大小)

[photoframeView_4 setTransform:transform_4];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

photoframeView_4.hidden = NO;
enlargeButton_4.hidden = YES; //隱藏放大的按鍵
normalButton_4.hidden = NO; //顯示放大後的按鍵
photoframe_4CurrentPOS.x = 512; //移動後的x座標

photoframe_4CurrentPOS.y = 374; //移動後的y座標

photoframeView_4.center = photoframe_4CurrentPOS;
angle_4  = 0*(PI/100); //旋轉UIView成正的
transformRotate_4 = CGAffineTransformMakeRotation(angle_4);
transform_4 = CGAffineTransformScale(transformRotate_4, 1, 1); //放大回原本大小
[photoframeView_4 setTransform:transform_4];
[UIView commitAnimations]; //執行動畫
}

所以,與其說是點選後開始變型(transform), 不如說是讓原本又小又歪的圖在點選後回復成原本的角度和大小。

2012年1月31日 星期二

『向下拉』提示動畫實作

在遊戲的進行中,雖然讓玩家自行摸索過關的技巧是玩遊戲的一種樂趣,但是我們又不希望玩家卡在一個關卡後,就失去了繼續玩下去的興緻了,所以在樂田麵包屋遊戲中,有很多的操作需要有提示才能讓玩家可以順利的過關。這裡示範一個向下拉動畫的實作。



要完成這樣的一個動畫,可以有2種不同的方法,你可以用setAnimation的方法,也可以用animationImages的方法,如果用setAnimation的方法只要準備2張圖片,一張是向下的箭頭,另一張是手指,然後將箭頭的圖片固定,使用setAnimation的方法讓手指的圖片移動y座標,這樣就可以產生手指向下滑動的動畫。

但是我們今天示範另一個用animationImages的作法:首先,如上圖準備5張分格的圖,分別命名為dragDown_1.png到dragDown_5.png。然後在.h宣告一個

UIImage *dragDown

接著在.m實作dragDownTip的程序


- (void)dragDownTip{
     dragDown.hidden = NO;
     dragDown.animationImages = [NSArray arrayWithObjects:
                            [UIImage imageNamed:@"dragDown_1.png"],
                            [UIImage imageNamed:@"dragDown_2.png"],
                            [UIImage imageNamed:@"dragDown_3.png"],
                            [UIImage imageNamed:@"dragDown_4.png"],
                            [UIImage imageNamed:@"dragDown_5.png"], nil];
     [dragDown setAnimationRepeatCount:3];
     dragDown.animationDuration = 1.5;
     [dragDown startAnimating];
}

當要執行動畫的時侯, 只要下指令:

[self dragDownTip];

就可以了。真是比setAnimation麻煩多了...當初我怎麼沒想到要用setAnimation的方法呢?真是不經一事,不長一智...

2012年1月27日 星期五

『樂田麵包屋』過關畫面分解

在樂田麵包屋遊戲中,每一次過關的時侯,都會有一段6秒鐘的過關畫面。雖然只有短短的6秒鐘,但是裡面包含了不算簡單的工作。在此將這些動作分解讓大家瞭解一下。




















這個畫面雖然只包含了4個元素(從上圖左手邊的objects可以看得出來),一張背景,一個小廚師的圖,一個獎牌,和小廚師身邊的星星。

實際上這6秒的畫面包含了以下的畫面:

1張背景


2張小廚師




- (void)chefAnimate{
    
    animationChef.animationImages = [NSArray arrayWithObjects:
                                    [UIImage imageNamed:@"chef_verygood1.png"],
                                    [UIImage imageNamed:@"chef_verygood2.png"],
                                     nil];
    
    [animationChef setAnimationRepeatCount:10];
    animationChef.animationDuration = 1.5;
    [animationChef startAnimating];
    
    
}


5張獎牌不同光澤


- (void)verygoodAnimate{
    
    animationVerygood.animationImages = [NSArray arrayWithObjects:
                                         [UIImage imageNamed:@"medalVerygood1.png"],
                                         [UIImage imageNamed:@"medalVerygood2.png"],
                                         [UIImage imageNamed:@"medalVerygood3.png"],
                                         [UIImage imageNamed:@"medalVerygood4.png"],
                                         [UIImage imageNamed:@"medalVerygood5.png"],
                                         [UIImage imageNamed:@"medalVerygood1.png"],nil];
    
    [animationVerygood setAnimationRepeatCount:10];
    animationVerygood.animationDuration = 1;
    [animationVerygood startAnimating];
    
    
}


1張閃爍不停的星星
- (void)starAnimation{
    starImage.alpha = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    starImage.alpha = 1.0;
    [UIView commitAnimations];
}




2012年1月24日 星期二

用presentModalViewController跳到另一個畫面

//如果是要從一個畫面(nib)跳到另一個畫面的方法,須指定要跳到的畫面,在這裡就是storeInfoViewController

- (IBAction)gotoStoreInfo:(id)sender {
    storeInfoViewController *storeView = [[storeInfoViewController alloc] initWithNibName:nil bundle:nil];
    [self presentModalViewController:storeView animated:YES];
}

//如果要回到剛才跳回來的畫面, 不需要指定要回到的畫面,反正它會自已回到剛才來的地方

- (IBAction)backToMenu:(id)sender {
    menuViewController *menuView = [[menuViewController alloc] initWithNibName:nil bundle:nil];
    [self presentModalViewController:menuView animated:YES];
}


2012年1月20日 星期五

用NSTimer讓程式慢個幾秒再做事

//在.h先宣告


NSTimer *delayTimer; //宣告一個NSTimer叫delayTimer(自已隨便取)

//在.m實作

delayTimer = [NSTimer scheduledTimerWithTimeInterval:1.5f  //在1.5秒後再去執行stopShakeSalt這個程序
                                                  target:self
                                                selector:@selector(stopShakeSalt)
                                                userInfo:nil
                                                 repeats:NO];

2012年1月13日 星期五

用AVAudioPlayer播放音效

在.h的宣告部份
#import <AVFoundation/AVFoundation.h> //先import AVFoundation後才能使用這個功能

AVAudioPlayer *titleBGM; //宣告一個新的聲音叫titleBGM(自已隨便取)是屬於AVAudioPlayer型式

- (void) playBGM; //宣告播放playBGM的功能

在.m的實作部份
//在init的時侯先設定titleBGM要播放音效檔
-(id)init{
    
    if (self = [super init]) {
        //下面紅字這一段是設定titleBGM
        NSBundle *bundle = [NSBundle mainBundle];
        NSString *path = [bundle pathForResource:@"menu" ofType:@"wav"];
        NSURL * url = [NSURL fileURLWithPath:path];
        titleBGM =[[AVAudioPlayer alloc] initWithContentsOfURL:url
                                                         error:nil];
        self->titleBGM.delegate = self;
    }
    return self;
}

//實作playBGM
- (void) playBGM{
    
    [titleBGM play];
}

//播放的使用方法

[titleBGM play];