2012年6月30日 星期六

Change UIActionSheet Style

 首先要記得繼承UIActionSheetDelegate

修改這個UIActionSheet的預設函式
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
    // 設定UIActionSheet的backround圖片
    UIImage *theImage = [UIImage imageNamed:@"selectbg.png"];    
    theImage = [theImage stretchableImageWithLeftCapWidth:32 topCapHeight:32];
    CGSize theSize = actionSheet.frame.size;
    // draw the background image and replace layer content  
    UIGraphicsBeginImageContext(theSize);    
    [theImage drawInRect:CGRectMake(0, 0, theSize.width, theSize.height)];    
    theImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    [[actionSheet layer] setContents:(id)theImage.CGImage];
}
然後調整UIActionSheet彈出後的按鈕樣式
UIActionSheet* Action = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"加入" otherButtonTitles:nil, nil];
    
[[[Action valueForKey:@"_buttons"] objectAtIndex:0] setImage:[UIImage imageNamed:@"select_bt.png"] forState:UIControlStateNormal];
    
[[[busAction valueForKey:@"_buttons"] objectAtIndex:1] setImage:[UIImage imageNamed:@"select_bt2.png"] forState:UIControlStateNormal];
    
[Action showInView:self.view];

Combine two Image

-(UIImage*)mergeImage:(UIImage*)first withImage:(UIImage*)second
{
    // build merged size
    CGSize mergedSize = CGSizeMake(Main_Pic_Width * 2 + 10, Main_Pic_Height);
    
    // capture image context ref
    UIGraphicsBeginImageContext(mergedSize);
    
    //Draw images onto the context
    [first drawInRect:CGRectMake(0, 0, Main_Pic_Width, Main_Pic_Height)];
    [second drawInRect:CGRectMake(Main_Pic_Width + 10, 0, Main_Pic_Width, Main_Pic_Height)]; 
    
    // assign context to new UIImage
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    // end context
    UIGraphicsEndImageContext();
    
    return newImage;
}

ScreenShot to Image

首先要#import "QuartzCore/CALayer.h"跟QuartzCore.framework

.m檔程式碼如下
UIGraphicsBeginImageContext(CGRectMake(mainImageStartX, mainImageStartY, Main_Pic_Width, Main_Pic_Height).size);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, CGAffineTransformMakeTranslation(-mainImageStartX, -mainImageStartY));

[self.view.layer renderInContext:context];

g_StartImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

FMDB

首先當然是先下載FMDB的SDK

並且加入libsqlite3.0.dylib的framework
然後按照我的習慣會做成一個DB的singleton方便使用

首先是.h檔

#import <Foundation/Foundation.h>
#import "FMDatabase.h"

@interface DBData : NSObject
@property (nonatomic) FMDatabase* db;
  
+(DBData *)getInstance;   
-(FMDatabase *)loadDB:(NSString *)dbName;  
@end
接著是.m檔

#import "DBData.h"

@implementation DBData
@synthesize db;

static DBData *instance = nil;   
 
+(DBData *)getInstance   
{   
    @synchronized(self)    
    {   
        if (instance == nil)    
        {   
            instance = [[self alloc] init];   
        }   
    }   
    return instance;   
}   
   
-(FMDatabase* )loadDB:(NSString *)dbName   
{   
    NSURL *appUrl = [[[NSFileManager defaultManager] 
                      URLsForDirectory:NSDocumentDirectory 
                      inDomains:NSUserDomainMask] lastObject];
    NSString *dbPath = [[appUrl path] stringByAppendingPathComponent:@"MyDatabase.db"];   
    db = [FMDatabase databaseWithPath:dbPath];
    
    if (![db open]) {       
        NSLog(@"Could not open db");       
    }
    else
    {
        NSLog(@"open db Success");
    }       
    
    return db;   
}  
@end
都準備好了之後,就可以在程式的各處使用了
在要使用DB的.h加上這兩行

#import "DBData.h"

@interface Search : UIViewController 
{
    DBData *instance;    
    FMDatabase *db; 
}
要使用的.m檔如下,這是新增的範例
instance = [DBData getInstance];   
db = [instance loadDB:@"MyDatabase.db"];
            
FMResultSet *rs = [db executeQuery:@"SELECT name, description from MyDB WHERE name = ?",name];
            
if ([rs next])
{       
  NSString *name = [rs stringForColumn:@"name"];       
  NSString *description = [rs stringForColumn:@"description"];       
}
else
{         
  if(![db executeUpdate:@"INSERT INTO MyInfo (name, description) VALUES (?,?)", name, @"strong"])
  {
    [self displayAlertViewMsg:@"新增我的最愛失敗" andTitle:nil];
  }
  else
  {
    [self displayAlertViewMsg:@"新增我的最愛成功" andTitle:nil];
  }
}

GADBannerView

首先加入 iAd.framework

接著在.h檔設定如下

#import <UIKit/UIKit.h>
#import "GADBannerView.h"

@interface QuoteContentViewController : UIViewController<GADBannerViewDelegate>
{
    GADBannerView *bannerView_;
}
.m檔的初始設定,adUnitID更換成自己的廣告id即可

    // Create a view of the standard size at the bottom of the screen.
    float tabBarHeight = [[[super tabBarController] tabBar] frame].size.height;
    float tempHeight = 480.0f - GAD_SIZE_320x50.height - tabBarHeight - 15.0f;
    
    bannerView_ = [[GADBannerView alloc]
                   initWithFrame:CGRectMake(0.0,
                                            tempHeight,
                                            GAD_SIZE_320x50.width,
                                            GAD_SIZE_320x50.height)];
    
    // Specify the ad's "unit identifier." This is your AdMob Publisher ID. a14f05024e9e617
    bannerView_.adUnitID = @"a14f6a9cd715868";
    
    // Let the runtime know which UIViewController to restore after taking
    // the user wherever the ad goes and add it to the view hierarchy.
    bannerView_.rootViewController = self;
    bannerView_.delegate = self;
    [self.view addSubview:bannerView_];
    
    // Initiate a generic request to load it with an ad.
    [bannerView_ loadRequest:[GADRequest request]];
最後如果廣告要求成功的話,會在這個函式收到

- (void)adViewDidReceiveAd:(GADBannerView *)view
{
}

Viewcontrol title area color

// 設定最上方的標題列
UIColor* color = [[UIColor alloc]initWithRed:0.03 green:0.7 blue:0.31 alpha:1];
self.navigationController.navigationBar.tintColor = color;
    
UILabel *titleText = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 200, 28)]; 
titleText.backgroundColor = [UIColor clearColor]; 
[titleText setFont:[UIFont boldSystemFontOfSize:28.0]]; 
[titleText setTextColor:[UIColor whiteColor]];
[titleText setText:@"我的標題"]; 
self.navigationItem.titleView = titleText;

FaceBook - post article & photo on the wall

首先
當然是要加上FB的SDK

然後在.h檔設定如下

#import "FBConnect.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate,FBDialogDelegate, FBSessionDelegate, FBLoginDialogDelegate,FBRequestDelegate>
{
}

// Facebook 
@property (nonatomic, retain) Facebook *facebook;
接下來到.m檔 MyAppId是自己在FaceBook申請的應用程式id
-(void)initFacebook
{
    // 初始化facebook
    facebook = [[Facebook alloc] initWithAppId:MyAppId andDelegate:self];
    
    // 記錄facebook登入的token
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) 
    {
        facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
        facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
    }
}
接下來修改AppDelegate的三個函式
-(void)applicationDidBecomeActive:(UIApplication *)application
{  
    [self extendAccessTokenIfNeeded];
}

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url 
{
    [self handleOpenURL:url];
    return NO;
}

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 
{
    [self handleOpenURL:url];
    return NO;
}
補上其中呼叫的兩個函式handleOpenURL跟extendAccessTokenIfNeeded
-(void)extendAccessTokenIfNeeded
{
    [[self facebook] extendAccessTokenIfNeeded]; 
}

-(BOOL)handleOpenURL:(NSURL *)url
{
    return [self.facebook handleOpenURL:url];
}
取得授權跟login
-(void)loginFacebook
{
    if(![facebook isSessionValid])
    {
        //取得相關授權
        NSArray *permissions = [[NSArray alloc] initWithObjects:
                                @"user_likes",
                                @"read_stream",
                                @"user_birthday",
                                @"publish_stream",
                                @"offline_access",
                                @"user_status",
                                nil];
        [self.facebook authorize:permissions];
    }
    else
    {
        [self fbDidLogin];
    }
}
login跟logout的內容
- (void)fbDidLogin 
{
    NSLog(@"fbDidLogin");
    [self storeAuthData:[[self facebook] accessToken] expiresAt:[[self facebook] expirationDate]];
}

- (void)fbDidLogout 
{
    NSLog(@"fbDidLogout");
    
    // Remove saved authorization information if it exists and it is
    // ok to clear it (logout, session invalid, app unauthorized)
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults removeObjectForKey:@"FBAccessTokenKey"];
    [defaults removeObjectForKey:@"FBExpirationDateKey"];
    [defaults synchronize];
}
接下來重頭戲來了,將文章跟照片post上FB
-(void)postFacebook
{
    NSLog(@"fbDidLogin");
    [self storeAuthData:[[self facebook] accessToken] expiresAt:[[self facebook] expirationDate]];
    
    currentAPICall = kAPIGraphUserPost;
    
    NSString *sMessage = [[NSString alloc] initWithString:[NSString stringWithFormat:@"3我要潑的訊息"]];
    
        NSMutableDictionary * params2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                         g_FBPostImage, @"picture",sMessage,@"message",
                                         nil];
    
        [facebook requestWithGraphPath:@"me/photos" 
                             andParams:params2 
                         andHttpMethod:@"POST" 
                           andDelegate:self];
}
如果不要潑圖片,只要潑訊息,可以將me/photos改成me/feed,然後g_FBPostImage, @"picture",這段拿掉即可
最後補上一些FB預設的函式,用以捕捉訊息
- (void)apiFQLIMe 
{
    // Using the "pic" picture since this currently has a maximum width of 100 pixels
    // and since the minimum profile picture size is 180 pixels wide we should be able
    // to get a 100 pixel wide version of the profile picture
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   @"SELECT uid, name, pic FROM user WHERE uid=me()", @"query",
                                   nil];
    [[self facebook] requestWithMethodName:@"fql.query"
                                 andParams:params
                             andHttpMethod:@"POST"
                               andDelegate:self];
}

- (NSDictionary *)parseURLParams:(NSString *)query {
    
 NSArray *pairs = [query componentsSeparatedByString:@"&"];
 NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
 for (NSString *pair in pairs) {
  NSArray *kv = [pair componentsSeparatedByString:@"="];
  NSString *val =
        [[kv objectAtIndex:1]
         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        
  [params setObject:val forKey:[kv objectAtIndex:0]];
 }
    return params;
}


- (void)storeAuthData:(NSString *)accessToken expiresAt:(NSDate *)expiresAt {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:accessToken forKey:@"FBAccessTokenKey"];
    [defaults setObject:expiresAt forKey:@"FBExpirationDateKey"];
    [defaults synchronize]; 
}

- (void)fbSessionInvalidated 
{
    NSLog(@"fbSessionInvalidated");
    
    UIAlertView *alertView = [[UIAlertView alloc]
                              initWithTitle:@"Auth Exception"
                              message:@"Your session has expired."
                              delegate:nil
                              cancelButtonTitle:@"OK"
                              otherButtonTitles:nil,
                              nil];
    [alertView show];
    [self fbDidLogout];
}


#pragma mark - FBRequestDelegate Methods
/**
 * Called when the Facebook API request has returned a response. This callback
 * gives you access to the raw response. It's called before
 * (void)request:(FBRequest *)request didLoad:(id)result,
 * which is passed the parsed response object.
 */
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response 
{
    NSLog(@"received response");
}

- (void)request:(FBRequest *)request didLoad:(id)result 
{
    NSLog(@"request:didLoad");
    
    haveFbRequest = false;
    
    if ([result isKindOfClass:[NSArray class]] && ([result count] > 0))
    {
        result = [result objectAtIndex:0];
    }
    
    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"成功分享到facebook了!" message:nil delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
    
    [alertView show];
}

- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
    NSLog(@"request fail");
    NSLog(@"Error message: %@", [[error userInfo] objectForKey:@"error_msg"]);
}




#pragma mark - FBDialogDelegate Methods

/**
 * Called when a UIServer Dialog successfully return. Using this callback
 * instead of dialogDidComplete: to properly handle successful shares/sends
 * that return ID data back.
 */
- (void)dialogCompleteWithUrl:(NSURL *)url 
{
    NSLog(@"dialogCompleteWithUrl.");
    
    if (![url query]) 
    {
        NSLog(@"User canceled dialog or there was an error");
        return;
    }
    
}