2010年7月27日 星期二

iOS 開發教學 - 使用 UIToolbar + Image Button

之前學習時很偷懶,一直覺得有了 Navigation controller 和 Tabbar controller 後,總覺得畫面已經沒甚麼好擺的,所以遲遲沒有試試 UIToolbar ,這次就順手筆記一下囉。

參考資料:


程式碼:

@interface UIImage (Extras)

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;

@end

@implementation UIImage (Extras)

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{

   UIImage *sourceImage = self;
   UIImage *newImage = nil;      
   CGSize imageSize = sourceImage.size;
   CGFloat width = imageSize.width;
   CGFloat height = imageSize.height;
   CGFloat targetWidth = targetSize.width;
   CGFloat targetHeight = targetSize.height;
   CGFloat scaleFactor = 0.0;
   CGFloat scaledWidth = targetWidth;
   CGFloat scaledHeight = targetHeight;
   CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
 
   if (CGSizeEqualToSize(imageSize, targetSize) == NO)
   {
       CGFloat widthFactor = targetWidth / width;
       CGFloat heightFactor = targetHeight / height;
     
       if (widthFactor > heightFactor)
           scaleFactor = widthFactor; // scale to fit height
       else
           scaleFactor = heightFactor; // scale to fit width
       scaledWidth  = width * scaleFactor;
       scaledHeight = height * scaleFactor;
     
       // center the image
       if (widthFactor > heightFactor)
       {
           thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
       }
       else
           if (widthFactor < heightFactor)
           {
               thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
           }
   }     
 
   UIGraphicsBeginImageContext(targetSize); // this will crop
 
   CGRect thumbnailRect = CGRectZero;
   thumbnailRect.origin = thumbnailPoint;
   thumbnailRect.size.width  = scaledWidth;
   thumbnailRect.size.height = scaledHeight;
 
   [sourceImage drawInRect:thumbnailRect];
 
   newImage = UIGraphicsGetImageFromCurrentImageContext();
   if(newImage == nil)
       NSLog(@"could not scale image");
 
   //pop the context to get back to the default
   UIGraphicsEndImageContext();
   return newImage;
}
@end

- (void)aButton:(UIButton *)sender
{
   switch (sender.tag) {
       case 1:
           NSLog(@"Facebook");
           break;
       case 2:
           NSLog(@"Twitter");
           break;
       case 3:
           NSLog(@"Tumblr");
           break;
       case 4:
           NSLog(@"Plurk");
           break;
       default:
           break;
   }
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

   // Override point for customization after application launch.
   //Initialize the toolbar

   UIToolbar *toolbar = [[UIToolbar alloc] init];
   toolbar.barStyle = UIBarStyleDefault;
   toolbar.alpha = 0.8;
 
   //Set the toolbar to fit the width of the app.
   [toolbar sizeToFit];

   //Caclulate the height of the toolbar
   CGFloat toolbarHeight = [toolbar frame].size.height;

   //Get the bounds of the parent view
   CGRect rootViewBounds = [[UIScreen mainScreen] bounds];
 
   //Get the height of the parent view.
   CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
 
   //Get the width of the parent view,
   CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
 
   //Create a rectangle for the toolbar
   CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);
 
   //Reposition and resize the receiver
   [toolbar setFrame:rectArea];

   NSMutableArray *barButtonItemList = [[NSMutableArray alloc] init];
   CGFloat thumbWidth = 42 , thumbHeight = 42;
   {
       UIImage *image = [[UIImage imageNamed:@"facebook_icon.png"] imageByScalingAndCroppingForSize:CGSizeMake(thumbWidth, thumbHeight)];
       UIButton *button = [[UIButton alloc] init];
       [button setTag:1];
       [button setImage:image forState:UIControlStateNormal];
       [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
       [button addTarget:self action:@selector(aButton:) forControlEvents:UIControlEventTouchDown];
       UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
       [button release];
       [barButtonItemList addObject:barButton];
       [barButton release];
   }
   {
       UIImage *image = [[UIImage imageNamed:@"twitter_icon.png"] imageByScalingAndCroppingForSize:CGSizeMake(thumbWidth, thumbHeight)];
       UIButton *button = [[UIButton alloc] init];
       [button setTag:2];
       [button setImage:image forState:UIControlStateNormal];
       [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
       [button addTarget:self action:@selector(aButton:) forControlEvents:UIControlEventTouchDown];
       UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
       [button release];
       [barButtonItemList addObject:barButton];
       [barButton release];
   }
   {
       UIImage *image = [[UIImage imageNamed:@"tumblr_icon.png"] imageByScalingAndCroppingForSize:CGSizeMake(thumbWidth, thumbHeight)];
       UIButton *button = [[UIButton alloc] init];
       [button setTag:3];
       [button setImage:image forState:UIControlStateNormal];
       [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
       [button addTarget:self action:@selector(aButton:) forControlEvents:UIControlEventTouchDown];
       UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
       [button release];
       [barButtonItemList addObject:barButton];
       [barButton release];
   }
   {
       UIImage *image = [[UIImage imageNamed:@"plurk_icon.png"] imageByScalingAndCroppingForSize:CGSizeMake(thumbWidth, thumbHeight)];
       UIButton *button = [[UIButton alloc] init];
       [button setTag:4];
       [button setImage:image forState:UIControlStateNormal];
       [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
       [button addTarget:self action:@selector(aButton:) forControlEvents:UIControlEventTouchDown];
       UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
       [button release];
       [barButtonItemList addObject:barButton];
       [barButton release];
   }
   [toolbar setItems:barButtonItemList];
 
   [window addSubview:toolbar];
 
   [window makeKeyAndVisible];
 
   return YES;
}

用 wget 下載 iOS SDK

實在是有時網路速度很龜速,所以才想到用其他方式來下載檔案。用到的東西有三個:



  • Firefox + Firebug plugin

  • wget

  • 一個申請過 Apple ID 的帳密


首先先用該帳密登入到 iPhone Dev Center ( https://developer.apple.com/iphone/index.action#downloads ),並開啟 firebug 網路功能,準備偵測封包,接著就去點選下載新版的 iOS SDK,此例為 Xcode 3.2.3 and iOS SDK 4.0.1 ,之後就可以看到相關的網路封包,如 GET http://adcdownload.apple.com/ios/ios_sdk_4.0.1__final/xcode_3.2.3_and_ios_sdk_4.0.1.dmg ,查看其細部的 Cookie 資料,找尋 ADCDownloadAuth=...


最後則可以用其他國外頻寬快的機器,使用 wget 進行下載


wget 'http://adcdownload.apple.com/ios/ios_sdk_4.0.1__final/xcode_3.2.3_and_ios_sdk_4.0.1.dmg' --header 'Cookie: ADCDownloadAuth=your_cookie_info'


收工!


2010年7月26日 星期一

[動畫] 新版鋼之鍊金術師








again - YUI


忘了是多久以前,看了第一版的鋼之鍊金術師,當時就覺得這部動畫很巧妙地描述一些人性層面的事情,有時候也會在想,到底要幾歲才適合看這部動畫呢?或許這都多慮了?生命自會找到出路吧?!


這幾天看了新版的鋼之鍊金術師,原先只是打發時間外加好奇新版到底加了什麼,然而我也忘了舊版少部分的內容跟結局,所幸這就樣當初第一次看吧?不知不覺地就追完整部動畫。說真的我還滿喜歡看這類型的,有點似淺又深的。我喜歡等價交換這個定理,就像以前國高中計算一些物理題目的動量、動位能守恆等等的,另外還有化學的動態平衡等等,或是最大亂度最低能量,都是一種口頭禪啊。


那究竟要追求什麼呢?又要失去什麼呢?


大學的時候,曾羨慕一些功課好的人,覺得他們總是能把課業、社團甚至娛樂與打工取的一種平衡,自己大概就傻傻地顧成績,但又沒有顧好,當自己學有微成,就看不起那些走捷徑的人。快進入碩班時,算是已經取的一些平衡,畢竟,一天只有 24 小時,回想起大一教我們程式的秋媛姐,當時總是提醒大家不要花太多時間在 BBS ,我不覺得她有說錯的地方,我卻也不覺得是對的。當時的 BBS 是另一種家,大家透過個人板、寢室板,用簡單的文字反而得到更多的互動。話說大一時還曾跟室友每天輪流寫寢記呢!當然蠢事也發生不少,像是幫室友認識某系的班花,或是認識學扮的男友,結果到現在還是一樣尷尬,那位從學伴變同系不同班的同學,甚至前陣子發現在同公司上班,哈。


至於現在的我到底要追求什麼?我也很常地問我自己,並還在追求答案。希望可以透過所學的,先拉拔家人,再求幫助更多的人吧!


啊,忘了一說,唱歌的 YUI ,第一次聽到唱歌是太陽之歌,聽學弟說,很多動畫歌也都是他唱的,真厲害。









2010年7月22日 星期四

[Linux] 使用 SSH Tunnel 連線至 Mac OSX @ Ubuntu 10.04

Mac OS X 有提供遠端桌面的服務,雖然可以設定密碼連線,但整個過程中似乎沒有加密?所以我就在 Ubuntu 上試著用 ssh tunnel 連到 Mac OS X。此目的是從 Ubuntu 機器遠端桌面到 Mac OS X 。


參考資料:



指令:


$ ssh -N -f -L 9000:localhost:5900 user@MAC_OS_X_IP


其中 ssh 參數資訊


     -N     Do not execute a remote command.  This is useful for just for‐
             warding ports (protocol version 2 only).

     -f      Requests ssh to go to background just before command execution.
             This is useful if ssh is going to ask for passwords or
             passphrases, but the user wants it in the background.  This
             implies -n.  The recommended way to start X11 programs at a
             remote site is with something like ssh -f host xterm.

     -L [bind_address:]port:host:hostport
             Specifies that the given port on the local (client) host is to be
             forwarded to the given host and port on the remote side.  This
             works by allocating a socket to listen to port on the local side,
             optionally bound to the specified bind_address.  Whenever a con‐
             nection is made to this port, the connection is forwarded over
             the secure channel, and a connection is made to host port
             hostport from the remote machine.  Port forwardings can also be
             specified in the configuration file.  IPv6 addresses can be spec‐
             ified with an alternative syntax:
             [bind_address/]port/host/hostport or by enclosing the address in
             square brackets.  Only the superuser can forward privileged
             ports.  By default, the local port is bound in accordance with
             the GatewayPorts setting.  However, an explicit bind_address may
             be used to bind the connection to a specific address.  The
             bind_address of “localhost” indicates that the listening port be
             bound for local use only, while an empty address or ‘*’ indicates
             that the port should be available from all interfaces.


簡言之,-f 是背景執行,-N 是用在 port forwarding,-L 就是關鍵的東西,依序代表本地端 Port ,以及目的端 IP、Port,而最後接的那個 USER@IP 代表要透過的機器。


以我的情境來說,我將透過本地端 Port 9000 (此乃隨意自訂的 Port)建立一個 ssh tunnel 到 MAC_OS_X_IP 機器上,並在 MAC_OS_X_IP 機器上連到 localhost:5900 (5900是Mac預設的遠端桌面 Port)。所以就等同於在 MAC_OS_X_IP 機器上,連線 localhost (此指的是 MAC_OS_X_IP 機器) 的 Port 5900 。


最後,我在原先的那台機器,也就是 Ubuntu 上,僅需使用 VNC 連到 localhost:9000 即可導到 MAC_OS_X_IP:5900 進行登入的動作。


[OSX] 粗淺地使用 ipfw @ Mac 10.6

距離上一次用 ipfw,大概已經是五六年前啦。主要是想要阻擋公司內部一些"彷彿中毒"電腦去 try 機器,另外,公司已經有強大的防火牆阻擋外部連進來,因此我只需限制公司內部的 IP 就行!此篇是最粗淺的設定筆記,並不適用其他常用的機器。除了 ipfw rules 外,其他的設定只是為了讓他可以開機就執行 ipfw 。

參考文件:



  1. Init

    • $ sudo mkdir /Library/StartupItems/Firewall

    • $ sudo touch /Library/StartupItems/Firewall/Firewall

    • $ sudo chmod ug+x /Library/StartupItems/Firewall/Firewall

    • $ sudo chmod o-rwx /Library/StartupItems/Firewall/Firewall

  2. /Library/StartupItems/Firewall/Firewall

    • !/bin/sh

      ########## file @ /Library/StartupItems/Firewall/Firewall

      # http://www.freebsd.org/doc/en/books/handbook/firewalls-ipfw.html

      # http://www.ibiblio.org/macsupport/ipfw/



      ipfw=`which ipfw`

      $ipfw -q -f flush

      cmd="$ipfw -q add "


      $cmd 00500 check-state


      $cmd 07999 allow all from x.y.My.PC1 to any

      $cmd 07999 allow all from x.y.My.PC2 to any

      $cmd 07999 allow all from x.y.My.PC3 to any

      $cmd 08999 deny all from x.y.0.0/16 to any

      $cmd 09999 allow all from any to any

  3. /Library/StartupItems/Firewall/StartupParameters.plist

    • {
      Description = "Firewall";
      Provides = ("Firewall");
      Requires = ("Network");
      OrderPreference = "None";
      Messages =
         {
         start = "Starting NAT/Firewall";
         stop = "Stopping NAT/Firewall";
         };
      }

其中 x.y.My.PC1 要留意設定,有時要記的加上常用的機器列表,別忘了加公司的 DNS,這樣才能你的機器才能連過去。