Sunday, June 17, 2012

Label with dynamic height

The below code creates the dynamic height to fit for the inputed text

-(void)createDynamicHeight
{
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 0, 300, 40)];
label.backgroundColor = [UIColor blackColor];
[self.view addSubview:label];
NSString *text = @"This is label with dynamic height";
label.text = text;
label.lineBreakMode = UILineBreakModeWordWrap;
    
// resize the height to fit the content
CGSize newLabelSize = [text sizeWithFont:label.font 
                       constrainedToSize:label.frame.size
                           lineBreakMode:UILineBreakModeWordWrap];
    
CGRect newFrame = instructions.frame;

if (newLabelSize.height > 40) {
      newFrame.size.height = newLabelSize.height;
} else {
      newFrame.size.height = 40
}
label.frame = newFrame;
label.numberOfLines = 0;

NSLog(@"Label height is %f", label.frame.size.height);
}

Thursday, June 14, 2012

Error: more than max 5 filtered album trying to register, this will fail

Per the subject, the following code may help to solve it.
I tried in my project, it seems work.


- (void)viewDidAppear:(BOOL)animated{    [super viewDidAppear:animated];    [self setModalInPopover:YES];}

Tuesday, June 12, 2012

Limit the number of characters in UITextView


#define MAX_LENGTH 50

// UITextView delegate

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {    
    
    NSLog(@"type %d char", myTextView.text.length);    
        
    if (myTextView.text.length >= MAX_LENGTH && range.length == 0)
    {
        NSLog(@"max length is reached");
       
        return NO; // return NO to not change text
    }
    
}

Tuesday, June 5, 2012

Limit the number of lines in UITextView




- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 
{
    
    // limit the number of lines in textview
    NSString* newText = [mytextView.text stringByReplacingCharactersInRange:range withString:text];

    // pretend there's more vertical space to get that extra line to check on
    CGSize tallerSize = CGSizeMake(mytextView.frame.size.width-15, mytextView.frame.size.height*2); 

    CGSize newSize = [newText sizeWithFont:mytextView.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
    
    if (newSize.height > mytextView.frame.size.height)
    {
        NSLog(@"two lines are full");
        return NO;
    }
    
    
    // dismiss keyboard and send comment
    if([text isEqualToString:@"\n"]) {
        [mytextView resignFirstResponder];
        
        return NO;
    }
    
    return YES;
}

Tuesday, May 15, 2012

Hide StatusBar, TabBar, NavigationBar


1. To hide the status bar:

[[UIApplication shareApplication] setStatusBarHidden:YES];


2. To hide the navigation bar:

self.navigationController.navigationBarHidden = YES;


3. To hide the tab bar:

MyController *myController = [[MyController alloc] init ];
myController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:myController animated:YES];
[myController release];

Monday, April 2, 2012

New app - PhotoUploads (Full version)

Full version of PhotoUploads is available in App Store. It lets you to upload unlimited photos to Facebook, Flickr, dropbox and own server.

The php script is included in the app for you to set up the server.

http://itunes.apple.com/us/app/photouploads/id505900653?mt=8


 


Friday, March 30, 2012

Autorelease, release, retain

在Objective-C中所有的物件都是指標,當我們建立一個物件時(由 alloc、new、copy 產生出來或是使用retain來取得從其他來源獲得的物件),我們不但配置了記憶體,同時也讓該物件的指標指向這個記憶體位址。 Objective-C使用reference counting的方式作為記憶體管理的機制,Reference Counting 的運作是基於 ownership。當程式要使用物件時,必須取得物件的 ownership,一個物件可以有很多 owner;而當程式不再使用物件時,則需要放棄 ownership。直到物件沒有任何 owner 時,物件就會自動被 dealloc。
物件第一次被建立時,只有一個owner的指標指向它的記憶體位址,所以它的reference count為1。若有新owner的指標指向該記憶體,它的reference count便會加1。相反的,如果我們不再需要這個指標,而將它release,該物件的reference count就會減1。當該物件的reference count變為零時,代表沒有指標指向它了,該物件的dealloc函式就會自動被呼叫,這時寫在dealloc裡的那些release指令就會一起被執行了,這塊記憶體就會被釋放掉。


在Objective-C建立物件有兩種方法,一種是手動配置記憶體並初始化該物件:


NSString *string = [[NSString alloc] init];
用這種方式宣告的物件,當我們不再需要使用時,必需手動呼叫release方法來釋放它。


另一種方法則是呼叫該類別的類別方法(Class method)直接建立該物件:


NSString *string = [NSString stringWithFormat:@"test string"];
這類方法所建立的物件我們不需要手動release它,當它被建立的同時,它也會被丟進一個叫做autorelease pool的「池子」裡。每當程式主要的loop執行完一次,就會檢查autorelease pool裡的物件是否還會被使用到,如果會就留著;如果不會就把它清掉。這種會把物件丟進autorelease pool的類別方法有個特點,就是他們的名稱開頭都會是該類別的字串。比如NSString,類別方法中開頭是stringXXX的,就會把建立的物件丟入autorelease pool。


要特別注意的是,autorelease跟release不同,release會馬上在執行後把retain count減1,而autorelease則是待會才會減1。另外,一但你把物件設定為autorelease之後,這個東西基本上就不算是你管的,你之後就不需要也不應該再去對它做release的動作了。


- (NSString *) getBookTitle {  
NSString *name = [[NSString alloc] initWithString:@"This is a book"];  
[name autorelease];  
return name; }


以上的code,因為name這個方法需要回傳值,如果第4行的[name autorelease]寫成了[name release],因為太早release掉name後,name就不會正確回傳了。不加上的話又會造成記憶體的泄漏(leaked)。所以這時候使用了autorelease就是正確的作法。上面的程式碼第2行常常會和autorelease合併簡寫為類似[[[NSString alloc] init] autorelease],或是把第3和4行合併簡寫為return [name autorelease]。



這裡提供幾個基本的原則,希望對還不熟悉記憶體管理的朋友們有些幫助:


  1. 如果是自已alloc或者retain的物件,最後一定要release掉。
  1. 用類別方法(Class method)建立的物件會被丟入autorelease pool,不需要手動釋放記憶體。



Reference:
http://bonjouryentinglai.wordpress.com/2010/02/10/objective-c-隨手筆記-ii-記憶體管理


http://marcelsite.heroku.com/posts/5-iPhone-s-alloc-init-new-retain-release-autorelease-copy-


http://log.bcse.tw/2011/05/ios-programming-tips-3.html