Sunday, January 29, 2012

Generate unique random integers

The following codes can generate 8 unique random integers.


-(NSMutableArray *)getEightRandom {
  NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
  int r;
  while ([uniqueNumbers count] < 8) {
    r = arc4random();
    if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
      [uniqueNumbers addObject:[NSNumber numberWithInt:r]];
    }
  }
  return uniqueNumbers;
}
If you want to restrict to numbers less than some threshold M, then you can do this by:
-(NSMutableArray *)getEightRandomLessThan:(int)M {
  NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
  int r;
  while ([uniqueNumbers count] < 8) {
    r = arc4random() % M; // ADD 1 TO GET NUMBERS BETWEEN 1 AND M RATHER THAN 0 and M-1
    if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
      [uniqueNumbers addObject:[NSNumber numberWithInt:r]];
    }
  }
  return uniqueNumbers;
}
If M=8, or even if M is close to 8 (e.g. 9 or 10), then this takes a while and you can be more clever.
-(NSMutableArray *)getEightRandomLessThan:(int)M {
  NSMutableArray *listOfNumbers = [[NSMutableArray alloc] init];
  for (int i=0 ; i<M ; ++i) {
    [listOfNumbers addObject:[NSNumber numberWithInt:i]]; // ADD 1 TO GET NUMBERS BETWEEN 1 AND M RATHER THAN 0 and M-1
  }
  NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
  int r;
  while ([uniqueNumbers count] < 8) {
    r = arc4random() % [listOfNumbers count];
    if (![uniqueNumbers containsObject:[listOfNumbers objectAtIndex:r]]) {
      [uniqueNumbers addObject:[listOfNumbers objectAtIndex:r]];
    }
  }
  [listOfNumbers release];
  return uniqueNumbers;
}
Source:http://stackoverflow.com/questions/6153550/ios-how-do-i-generate-8-unique-random-integers

Tuesday, January 24, 2012

Create In-App email sent from iPhone, iPad

Before write the code, set up the followings in the project.


Add the Framework
Add the MessageUI framework to your projects Frameworks group folder in Xcode




Import Message Framework
Import MessageUI.h and MFMailComposeViewController.h to the header file of the delegate
Make your Delegate
Indicate that your delegate class is the delegate by including this <MFMailComposeViewControllerDelegate> in the 
.h file
Implement the Delegate Method
Implement the didFinishWithResult MFMailComposeViewControllerDelegate delegate method and make sure to return control to the program by sending the dismissModalViewControllerAnimated message.
-(void)composeMail 
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:@"mySubject"];
// Set up recipients
    
NSArray *toRecipients = [NSArray arrayWithObject:@"myRecipient@abc.com"]; 
[picker setToRecipients:toRecipients];
    
// Fill out the email body text
NSString *emailBody = @"message body.";
[picker setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:picker animated:YES];
        [picker release];
}

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
{

         [self dismissModalViewControllerAnimated:YES];

}

-(void)launchMailAppOnDevice
{




        NSString *str = [NSString stringWithFormat:@"mailto:%@&subject=mySubject",recipient];
    
NSString *body = @"&body=message content";
NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}






Calculate the height of long text (dynamic height of label, cell, textview)

If you want the dynamic height for tableviewCell, label, textview, you have to calculate the height of the long text within the desired width, either of following method can be used.



- (CGSize)sizeWithFont:(UIFont *)font
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode




The below code can obtain the height.

CGSize boundSize = CGSizeMake(desiredWidth, CGFLOAT_MAX);
CGSize myTextSize = [myText sizeWithFont:myFont constrainedToSize:boundSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat myTextHeight = myTextSize.height;
Remark:

Use CGFLOAT_MAX (or a big number) for the height value in CGSizeMake method.

Thursday, January 19, 2012

When app start up, use splashView with ActivityIndicatorView

Add SplashScreenVC class in the project.
Use the below code to replace the original code in yourAppDelegate.m:

- (void)applicationDidFinishLaunching:(UIApplication *)application

{
    SplashScreenVC *splashScreenVC = [[SplashScreenVC alloc] initWithNibName:@"SplashScreenVC" bundle:nil];
    self.window.rootViewController = splashScreenVC;
    [self.window makeKeyAndVisible];
}


In SplashScreenVC, import yourAppDelegate.h and add the below code:


-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self performSelector:@selector(gotoRootVC) withObject:nil afterDelay:1.0];
}

-(void)gotoRootVC
{
    
    SQLiteTutorialAppDelegate *delegate = (SQLiteTutorialAppDelegate *)[UIApplication sharedApplication].delegate;
    delegate.window.rootViewController = delegate.tabBarController;
    [delegate.window makeKeyAndVisible];
}

-(void)viewDidLoad
{

    CGRect r = [UIScreen mainScreen].applicationFrame;
    UIView *activityView = [[[UIView alloc] initWithFrame:r] autorelease];
    self.view = activityView;
    
    activityView.backgroundColor = [UIColor blackColor];
    activityView.alpha = 0.5;
    
    UIImageView *imgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourImage.png"]] autorelease];
    [activityView addSubview:imgView];
    
    CGRect wheelR = CGRectMake(r.size.width / 2 - 12, r.size.height / 2 - 12, 24, 24);
    UIActivityIndicatorView *activityWheel = [[UIActivityIndicatorView alloc] initWithFrame:wheelR];
    activityWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
    activityWheel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                      UIViewAutoresizingFlexibleRightMargin |
                                      UIViewAutoresizingFlexibleTopMargin |
                                      UIViewAutoresizingFlexibleBottomMargin);
    [activityWheel startAnimating];
    [activityView addSubview:activityWheel];
}


Tuesday, January 17, 2012

UIActivityIndicatorView

網路傳輸時 UIActivityIndicatorView 的動作

這已經是習慣了,大家都習慣要有這個符號出現。
當你的程式有使用到網路傳輸,通常就需要放一個 UIActivityIndicatorView 在畫面上,讓使用者知道目前正在傳輸中,以免讓人覺得沒有回應,像是當機一樣。

可是,為何你照著書本範例加到自己的程式卻不會動呢?
原因是:UIKit 的 main thread 一次只有做一件事,如果你在 ViewController 傳輸檔案,那麼其他的動作會等傳輸完之後再接下去做,所以你要另外再生出一個 thread 去處理 UIActivityIndicatorView 的動作。

首先,在 .h 檔的 @interface 內加上
UIActivityIndicatorView *activityIndicator;
以及
@property (nonatomicretain) UIActivityIndicatorView *activityIndicator;

另外,再加上兩個 method
-(void)actIndicatorBegin;
-(void)actIndicatorEnd;

開啓 .m 檔,在 @implementation 的下面加上
@synthesize activityIndicator;
在 (void)loadView 內把你的 UIActivityIndicatorView 加上去你要的 View 上面,我這裡加在 UIToolbar 工具列裡面的一個 UIBarButtonItem 按鈕
activityIndicator = [[UIActivityIndicatorView allocinitWithFrame:CGRectMake(002424)];
[activityIndicator setCenter:CGPointMake(1212)];
[activityIndicator setHidesWhenStopped:YES];
[activityIndicator setActivityIndicatorViewStyleUIActivityIndicatorViewStyleWhite];
[activityIndicator startAnimating];
UIBarButtonItem *activityItem = [[[UIBarButtonItem allocinitWithCustomViewactivityIndicator]autorelease];

再把這個 UIBarButtonItem 加到 UIToolbar 內
NSArray *items = [NSArray arrayWithObjects:activityItem, nil];
toolbarTop.items = items;

在處理網路傳輸之前先執行這個 thread
[NSThread detachNewThreadSelector@selector(actIndicatorBegintoTarget:self withObject:nil];

//需要時間下載檔案的程式寫在這裡
url = [NSURL URLWithString:@"http://網址/圖片檔.jpg"];
img =[UIImage imageWithData:[NSData dataWithContentsOfURL:url]];

網路傳輸完之後再執行這個 thread
[NSThread detachNewThreadSelector@selector(actIndicatorEndtoTarget:self withObject:nil];

再加上這兩個 method 開關旋轉狀態
- (void) actIndicatorBegin {
[activityIndicator startAnimating];
}
-(void) actIndicatorEnd {
[activityIndicator stopAnimating];
}

Source: http://ipdevelop.blogspot.com/2010/10/uiactivityindicatorview.html

Saturday, January 14, 2012

Build Dictionary with Array inside


   
NSMutableDictionary *dict11 = [[NSMutableDictionary alloc] init];
// init two array with elements
NSArray *md = [[NSArray alloc] initWithObjects:@"TFT", @"STN", @"OLED", nil];
NSArray *dss = [[NSArray alloc] initWithObjects:@"LED", @"power", nil ];

// init dictionary with Array and key
dict11 = [NSDictionary dictionaryWithObjectsAndKeys: md, @"MD", dss, @"DSS", nil];

// dump key into console
for (id key in dict11) NSLog(@"%@ - %@", key, [dict11 objectForKey:key]);

// init NSArray with objects with "MD" key
NSArray *array1 =[[NSArray alloc] initWithObjects:[dict11 objectForKey:@"MD"],nil];

// dump the NSArray content to console
for (id str in array1) NSLog(@"array1 -%@", str);
   

Sunday, January 8, 2012

extract the substring from NSString

Extract the substring from/to certain position:



[myString substringToIndex:index];
[myString substringFromIndex:index];

Extract the substring from beginning to the particular position:

NSRange end = [longString rangeOfString:@";"];
NSString *shortString =[longString substringWithRange:NSMakeRange(0, end.location)]];
NSLog("%@", shortString);

Extract a string between two characters:

NSRange start = [longString rangeOfString:@"("];
NSRange end = [longString rangeOfString:@")"];
NSString *shortString = [longString substringWithRange:NSMakeRange(start.location, end.location)]];
NSLog("%@", shortString);