2016年1月20日 星期三

iOS筆記:delegate不會被呼叫的可能性

xxxDelegate not called
xxxDelegate never called
⋯⋯以上關鍵字下Google還蠻找到同伴的(笑)


1、會呼叫delegate的物件是nil
包含忘記alloc initlocal variable提早被釋放
還是建議需要delegate的物件是instance variable比較好

2016年1月19日 星期二

2016年1月14日 星期四

2016年1月12日 星期二

2016年1月11日 星期一

iOS筆記:自動調整View位置,讓UITextField不被鍵盤擋住

UITextField在螢幕的下方,一進入editing模式,鍵盤會跳出,此時UITextField是整個被鍵盤蓋住的。
原理:在鍵盤要出現之前調整VC.view的frame,整個往上移動到UITextField可以完整被看到。

加入UITextFieldDelegate 和一個變數 UITextField * editingTextField,指定textField.delegate


//加入觀察
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}
//解除觀察
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                          name:UIKeyboardWillShowNotification
                                          object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                          name:UIKeyboardWillHideNotification
                                           object:nil];
}
//鍵盤出現/消失:調整view
- (void)keyboardWillShow:(NSNotification *)notification {
    
    NSDictionary* info = [notification userInfo];
    CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGPoint itemOrigin = [editingTextField convertPoint:editingTextField.frame.origin toView:self.view];
    CGFloat itemHeight = editingTextField.frame.size.height;
    CGRect visibleRect = self.view.bounds;
    visibleRect.size.height -= (keyboardSize.height+itemHeight);
    //BOOL tmp =CGRectContainsPoint(visibleRect, itemOrigin);
    
    //move up view if keyboard hide the textfield
    if (!CGRectContainsPoint(visibleRect, itemOrigin)){
        CGRect rect = self.view.frame;
        rect.origin.y -= keyboardSize.height;
        [UIView animateWithDuration:1.0 animations:^{
            self.view.frame = rect;
        }];
    }
}
- (void)keyboardWillHide:(NSNotification *)notification {
    CGRect rect = self.view.frame;
    rect.origin.y= 64; //64 =navgation bar height
    [UIView animateWithDuration:1.0 animations:^{
        self.view.frame = rect;
    }];
}
#pragma mark - textField Delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    return YES;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField{
    editingTextField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [textField resignFirstResponder];
}




2016年1月8日 星期五

2016年1月7日 星期四

iOS筆記:NSURLSession for ftp requests (2) 和一個EXC_BAD_ACCESS紀錄

標題真長。
聽說NSURLSession的 download, upload request只針對HTTP,不知改了沒
先不提這個,來研究apple 的 FTP sample


2016年1月5日 星期二

iOS筆記:一個簡單的GCD timer demo

從初學OC後一年才發現我當初看的參考書完全沒教任何有關thread的東西
用過發現GCD真的是最容易用的一個(點頭

這是用GCD仿製NSTimer,讓這個名叫action的thread每0.1秒醒來去執行prepareAction的方法
相較於NSTimer的優勢在於:
一旦用了多工,NSTimer要是不在同條線上是關不掉的!
然後關了又開開了又關⋯⋯開了幾個就累積幾個同樣的timer
用GCD的寫法既可以多工又不用怕要怎麼處理關掉的情況(起碼actionFlag是在main thread去設定的),只要block內的程式碼結束了這條新開的thread就會被回收走了
BTW, GCD中用NSTimer是沒有反應的
BTW2,  要重複執行的方法一樣是在action thread裡run
還有記得更新UI的時候要把它拉去main thread去執行
(同場加映stackoverflow問答:Timer inside global queue is not calling in iOS

dispatch_async(dispatch_queue_create("action", nil), ^{
    //flag關掉thread會自己結束
    while (actionFlag) {
        [self prepareAction];
        [NSThread sleepForTimeInterval:0.1f];
    }
});



話說要如何改寫?
把NSTimer scheduledTimerWithTimeInterval的部分直接用上述程式碼取代,selector跟Interval放進while(repeats=YES)裡

iOS筆記:NSURLSession和CFNetwork的一些特性

  1. NSURLSession底層是CFNetwork
  2. NSURLSession預設Accept-Encoding: compress, gzip,CFNetwork預設是無。
  3. (BTW聽說資料量小的用壓縮反而會讓檔案變大,android預設也是無)
  4. 送出去的封包會切成header+body共兩個封包(這用wireshark在TCP層看得到)。如果是一般的web server是不用在意,若是燒板子的機器要特別注意封包是如何接收的
  5. 用CFNetwork接回傳就跟下載處理一樣要一個buffe一個一個接收再拼起來

2016年1月4日 星期一

iOS筆記:動畫圖片 UIImageView Animation

饒是我常常去翻文件結果還是漏看了這神奇的玩意(woot)
iOS2.0以後就有了怎麼一直都不知道


效果同等於android的 animation-list

開storyboard,拉一個image view到view controller上
按住control創一個IBOutlet叫做animationImageView
在viewDidLoad放上以下code,一進入view就會看到圖片在動
用animatedImageNamed: 會load所有step_img開頭的圖片,所以只要每張圖片檔名照順序存檔(step_img0, step_img1, step_img2, step_img3 ...)拉到專案就行了

self.animationImageView.image = [UIImage animatedImageNamed:@"step_img" duration:0.5f];
[self.animationImageView startAnimating];

(話說我買了 Appcoda出的中譯本,結果腦袋被夾了點了跟缺貨書籍一同出貨)