2013年8月22日 星期四

AVAudioPlayer 在使用 ARC 的情況下無法播放音效

- (IBAction)startMusic:(id)sender {

    NSError *error = nil;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Harlem_Shake" ofType:@"mp3"];
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    AVAudioPlayer *playMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
    
    playMusic.delegate = self;
    [playMusic play];
}

上面 code 打完後超納悶,

一個字一個字檢查了十來次,

明明就沒有打錯,音效卻死不出來。


最後終於找到了答案:

ARC 機制會自動新增一個 AVAudioPlayer 的 release,

這個 release 會在離開它所在的 method 後隨即被 dealloc 掉。

所以上面那段 code 執行到 [music play]; 時,

音樂雖然開始播了,

但下一秒 music 物件立即被 dealloc 掉了,

所以不會有任何音效播出。


解決方法將 AVAudioPlayer 物件宣告在 .h 檔,

並加入 strong 型別
@property (strong, nonatomic) AVAudioPlayer *playMusic;
就解決了



2013年6月18日 星期二

如何解決 Keyboard 擋住 TextField 的問題?


Beginning...



按下任一欄位,準備輸入文字時...




如何解決 Keyboard 擋住 TextField 的問題呢?


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //指定 TextField 將使用其 delegate
    self.nameField.delegate = self;
    self.numberField.delegate = self;
    
    //向 NotificationCenter 申請註冊,在 UIKeyboardDidShowNotification 時,
    //會呼叫 keyboardDidShow (自訂的) 這個 selector。
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidShow:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    //向 NotificationCenter 申請註冊,在 UIKeyboardWillHideNotification 時,
    //會呼叫 keyboardWillHide (自訂的) 這個 selector。
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

-(void) keyboardDidShow: (NSNotification *) notification {
    
    //取得鍵盤高度
    NSValue * value = [[notification userInfo] valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGFloat keyboardHeight = [value CGRectValue].size.height;
    //以動畫的方式,將 View 的 Y軸 往上移一個鍵盤高
    [UIView animateWithDuration:0.3f animations:^
     {
         CGRect frame = self.view.frame;
         frame.origin.y -= keyboardHeight;
         self.view.frame = frame;
     }
     ];
}

-(void) keyboardWillHide: (NSNotification *) notification {
    
    NSValue * value = [[notification userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey];
    CGFloat keyboardHeight = [value CGRectValue].size.height;
    
    [UIView animateWithDuration:0.3f animations:^
     {
         CGRect frame = self.view.frame;
         frame.origin.y += keyboardHeight;
         self.view.frame = frame;
     }
     ];
}


最後記得,註冊過的 Observer 要 release 掉

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    
    //只要有向 Notification Center 申請註冊,要記得 remove 掉
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}



2013年6月8日 星期六

iOS 5 -> iOS 6 的變更:view 的指定支援旋轉 method

指定旋轉支援的方向:

iOS 5

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
        return (toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
}

到 iOS 6 後改為

//是否支援自動旋轉 
- (BOOL)shouldAutorotate {
    return YES; 
} 

//支援的方向 
- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; 
} 

//預設的方向 
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {    
    return UIInterfaceOrientationPortrait; 
}

那與一開始在 Target 宣告有何不同?



在 Target 宣告時有點類似在 interface 裡宣告,
也就是如果 ViewController 沒有宣告上面那三個 method 時,
會自動套用在 Target 宣告的支援旋轉方向,
而寫在程式碼的三個 method 會把 Target 的宣告 override 掉,
使用時機是想要在各個 View 客制自己支援的旋轉方向。




更多資訊可參考 Apple 的文件 Supporting Multiple Interface Orientations:http://ppt.cc/jUZl



2013年4月30日 星期二

超方便的Xcode外掛KSImageNamed-Xcode,當我們呼叫imageNamed:時,自動浮現專案

裡的圖片清單供我們選擇

 https://github.com/ksuther/KSImageNamed-Xcode


 

2013年4月9日 星期二

型別轉換

整數(或浮點數)轉成字串,用 NSString 的 stringWithFormat 就作得到了
(改成 %f 或 %g 就可以把浮點數轉成字串):

NSString *myNewString = [NSString stringWithFormat:@"%i", myValue];



至於字串轉成整數或浮點數,可以用 NSString 中的 intValue 、floatValue 和 doubleValue 等方法進行:

double myDouble = [myString doubleValue];



以下是把浮點數轉成最接近的整數方法:

int myInt = (int)(myDouble + (myDouble>0 ? 0.5 : -0.5));