Posted on

UIView及繪圖練習範例APP

作業目標:Youtube操作影片
練習原始碼:homework0803

這個作業主要是在練習對view以及簡單的繪圖的操作,還有timer的使用
因此我截錄一些我覺得是練習關鍵的程式碼

下面的是viewController的相關程式碼

一個個出現的程式碼,按下show按鈕時觸發

- (IBAction)showButtonClick {
    [self clearButtonClick];
    [self.circleNumber resignFirstResponder];
    total = [self.circleNumber.text integerValue];
    index = 0;
    //設定間隔一個個產生circle
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addItems:) userInfo:NULL repeats:YES];
}

取得圓圈排列坐標的程式碼,傳入值為圓半徑及角度

//取得坐標
- (CGPoint)getPoint:(int) radius withAngel:(CGFloat) degrees{

    int y = sin(degrees * M_PI / 180)*radius;
    int x = cos(degrees * M_PI / 180)*radius;
    CGPoint btCorner = CGPointMake(x, y) ;
    return btCorner;
}

下面的程式碼則是在被新增的UIView物件裡面

顯示動畫,這邊要注意的是因為定位點的關係,由於我們希望元件的縮放是以view的中心來做縮放
所以改變的值是self.bounds,一般我們在做元件內部繪圖事件,都會使用self.bounds
而self.frame則是在外部設定物件資訊時使用。

-(void) playAnimation{
    [UIView animateWithDuration:0.5f
                     animations:^{
                         self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 50, 50);
                     }completion:^(BOOL finished) {
                         [UIView animateWithDuration:0.5f
                                          animations:^{
                                               self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 30, 30);
                                          }completion:^(BOOL finished) {
                                          }];

                     }];
}

另外,因為- (id)initWithFrame:(CGRect)frame被呼叫的時間是在circle被新建的時後,而不是在被加到畫面時,
為了落實動畫的被執行時間,所以我又實作了layoutSubviews這個方法,
並加上BOOL init當今天是第一次被呼叫時,才會執行playAnimation

-(void)layoutSubviews{
    if(init){
        [self playAnimation];
        init = NO;
    }
}

然後實作按下後縮小離開時恢復大小的功能

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [UIView animateWithDuration:0.2f
                     animations:^{
                         self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 0, 0);
                     }
                     completion:^(BOOL finished) {
                     }];
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    [UIView animateWithDuration:0.2f
                     animations:^{
                         self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 30, 30);
                     }
                     completion:^(BOOL finished) {
                     }];

}

原始碼下載:homework0803

Posted on

上課筆記(五) – UIView操作及繪圖介紹

view介紹

  1. UIWindow是會在一開始便被xcode建立起來,裡面有很多view。
  2. View的操作:
    1. 於上層操作subview: 在supervview裡是用MutableArray的index去管理subView,這index就是tag,tag=0是代表subview自己。
      [self addSubView: view];//新增view
      [self insertSubView: view atIndex:0];//新增view在layer0
      [self insertSubView:view belowSubview:upView];//新增view在upView之下
      [self insertSubView:view aboveSubview:upView];//新增view在upView之上
      [self exchangeSubviewAtIndex:0 withSubviewAtIndex:1];//將第0層的物件和第1層的調換
      UIView view = [self viewWithTag:1];//取出在storyboard中tag為1的物件
    2. 移除自己: [view removeFromSuperview];
    3. 設為隱藏:[view setHidden:YES];
  3. 繪圖資訊相關的包括CGRect和CGSize及CGPoint,可以用NSValue包起來
        //將NSRect放入NSArray中
        NSMutableArray *array = [[NSMutableArray alloc] init];
        NSValue *value;
        CGRect rect = CGRectMake(0, 0, 320, 480);
        value = [NSValue valueWithBytes:&rect objCType:@encode(CGRect)];
        [array addObject:value];
        NSLog(@"array:%@",array);
    
        //從Array中提取
        value = [array objectAtIndex:0];
        [value getValue:&rect];
        NSLog(@"value:%@",value);
  4. view有兩個用來描述其資訊的rect:framebounds
    這個網頁有說明這兩者的不同:http://n11studio.blogspot.tw/2012/06/frame-bounds.html
    值得一題的是這兩者的定位點不同,bounds是在畫面的中心,frame則是在左上角。

    1. Frame:Frame指定了View相對於其父View座標系的位置和大小,用在想要加入一個新產生的view時。
    2. Bounds:Bounds則是view相對於自身坐標系的位置和大小,bounds的起點通常都是(0,0)。處理事件或要畫內部的元件時使用。
    3. Center:顧名思義就是view的Frame的中心。
  5. 要注意,在viewDidLoad裡取得的frame和viewWillAppear裡的並不一樣,在viewWillAppear裡時的x及y坐標位置才會被移到正確位置。
  6. 元件自動縮放:imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  7. UIView的各個函數呼叫時間(請見此),以下說明幾個我曾用過的:
    1. setNeedsDisplay:讓uiview重新執行drawRect
    2. setNeedsLayout:重新計算view layout的大小
    3. layoutSubviews:需要調整subview的大小時呼叫(詳細解說
    4. 其他view相關處理事件
      – didAddSubview:
      – willRemoveSubview:
      – willMoveToSuperview:
      – didMoveToSuperview
      – willMoveToWindow:
      – didMoveToWindow
    5. view的動畫處理相關
      + animateWithDuration:delay:options:animations:completion:
      + animateWithDuration:animations:completion:
      + animateWithDuration:animations:
      + transitionWithView:duration:options:animations:completion:
      + transitionFromView:toView:duration:options:completion:

Drawing介紹

    1. 每次繪圖都需要取出繪圖物件:CGContextRef ctx = UIGraphicsGetCurrentContext();
    2. 畫三角型範例:
      - (void)drawRect:(CGRect)rect
          CGContextRef context = UIGraphicsGetCurrentContext();
          [[UIColor whiteColor] set];
          UIRectFill([self bounds]);
          CGContextBeginPath(context);
          CGContextMoveToPoint(context, 50, 50);
          CGContextAddLineToPoint(context, 50, 150);
          CGContextAddLineToPoint(context, 150, 50);
          CGContextClosePath(context);
      
          [[UIColor blueColor] setFill];
          [[UIColor blackColor] setStroke];
          CGContextDrawPath(context, kCGPathEOFillStroke);
      }
    3. 畫圓型範例:
      - (void)drawRect:(CGRect)rect
      {
          CGContextRef ctx = UIGraphicsGetCurrentContext();
          CGContextAddEllipseInRect(ctx, rect);
          CGContextSetFillColor(ctx, CGColorGetComponents([[UIColor blueColor] CGColor]));
          CGContextFillPath(ctx);
      
      }

 

Posted on

切換View會用到的函數

切換UIViewController的兩種方式

1. 有NavigationController時

方法一:右側進入

SecondViewController* svc=[[SecondViewController alloc]init];
[self.navigationController pushViewController:svc animated:YES];

返回到上一頁

[self.navigationController popViewControllerAnimated:YES];

方法二:下面切入

SecondViewController* svc=[[SecondViewController alloc]init];
[self.navigationController presentModalViewController:svc animated:YES];

返回到上一個UIViewController

[self.navigationController dismissModalViewControllerAnimated:YES];

2、没有NavigationController的切換方法

SecondViewController* svc=[[SecondViewController alloc]init];
[self presentModalViewController:svc animated:YES];

返回到上一個UIViewController

[self dismissModalViewControllerAnimated:YES];

取得子viewController或父ViewController的方式

假設View A是來源的ViewController,而View B是目標ViewController。
1.取得子viewController

((B *)self.presentedViewController).屬性名

2.取得父viewController

((A *)self.presentingViewController).屬性名

其中括號和類名是一種強制轉類型的用法。

Posted on

簡易記帳APP範例

source code在此:範例檔案下載AppPrototype

難得周日在家,就把昨天老師說的練習做完
老實說其實我弄很久(大概有八~九小時跑不掉= =)
可見真的很不熟悉,debug之類都超級慢的

首先就是在跳去圖表的地方,
原本在實作實際功能前可以正常出現圖表,後來不知為何會當掉,
光這個無聊的bug就找了兩三小時(遮臉)

後來發現是因為下面這段程式碼

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        InputViewController * inputCon = segue.destinationViewController;
        inputCon.delegate = self;
}

因為只要是storyboard控制的頁面切換,都會呼叫prepareForSegue
我同時用storyboard去切換新增資料和圖表頁面,
所以圖表的segue.destinationViewController不是InputViewController就會跳錯誤。

在這邊也要說,老師說的inputCon.delegate等於setDelegate是很重要的
因為錯誤訊息一直說沒有setDelegate這個方法
結果我還一直傻傻看不懂是什麼意思~>”<~
(老師上課有說!妳有沒有在聽阿!)

然後第二個遇到的困難,就是我要在轉圖表畫面時,需要把現有資料傳至圖表畫面
一開始我還傻傻的在那又把CostViewController弄一個@protocol
想說要實作一個delegate機制,又是一方面要實作別人的delegate,又要是別人的protocol,
搞得我好混亂阿~

後來才發現delegate似乎是被呼叫者,要把資料傳給呼叫者時才需使用(不確定,有錯請指正)

後來為了要傳遞資料,我不去使用storyboard的切換頁面方式,改使用程式去自行切換頁面
以下為傳送列表資料的程式碼

- (IBAction)showPieChart:(id)sender {
    PieChartViewController * pieController = [[PieChartViewController alloc] init];
    [self.navigationController pushViewController:pieController animated:YES];
    [pieController showPieChart:self record:self.record];
}

【附記一下切換viewController的相關方式】

最後要做的是實作修改和刪除資料的功能
第一步是先將CostViewController實作UITableViewDelegate

@interface CostViewController : UITableViewController<inputViewControllerDelegate,UITableViewDelegate>

本來我還很害怕實作完還要設什麼delegate,或還要自己去呼叫該方法,
結果太令人開心了,只要實作了tableView,按table cell時他就會自己呼叫(灑花)

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    //修改該筆資料
    InputViewController *inputCon = [self.storyboard instantiateViewControllerWithIdentifier:@"inputCon"];
    [self.navigationController pushViewController:inputCon animated:YES];
    [inputCon modifyData:self.record[indexPath.row] forKey:indexPath.row];
    inputCon.delegate = self;
}

不過這樣子我還是遇到了一個問題,就是叫出來的畫面是一片黑。
百思不得其解也找不出原因,
後來嘗試的把原本在storyboard裡InputViewController和CostViewController的連接關係拿掉,
突然畫面就又跑出來了。

初步推論是或許一個畫面若用storyboard來切換就會無法自己寫程式碼去切換,
所以當有一個畫面有兩個按鈕都可以連接到時,就需要都自己用程式碼去做掉切換的動作。

剩的就把功能實作完就大功告成囉!

畫面介紹:一進入APP時的畫面
螢幕快照 2013-08-18 下午2.56.15
新增/修改記帳資料的畫面
螢幕快照 2013-08-18 下午2.56.32
帳目總計圖表
螢幕快照 2013-08-18 下午2.56.38

source code在此:範例檔案下載AppPrototype

Posted on

上課筆記(四) – Naming Convention、記憶體管理

Naming Convention

  1. 命名原則:
    1. 具解釋性
    2. 清楚
    3. 不會混淆
  2. 類別名稱:
    1. 第一個字大寫
    2. 前置namespace(在新增專案時會有Class Prefix,就是在設定這個)
    3. 駝峰式的寫法
  3. 變數名稱
    1. 變數類型不需特別表明,可以用名稱去讓人聯想型別,例:
      BOOL isEditable;
      NSString * accountName;
      NSMutableArray * mailBoxes;
      UIImage * previewPaneImage;
      NSDictionary * messageDict;
  4. 方法名稱:可以清楚表明意思
  5. 參數名稱:避免和ivar同名

 記憶體管理(IOS沒有gc)

  1. 配置記憶體:alloc;清除記憶體:dealloc
  2. zomble:不該用到卻用到(值為nil);memory leak:已沒辦法存取卻未把記憶體清掉
  3. 使用arc比較容易發生zomble,不用arc則容易發生memory leak。
  4. 若是有一段程式碼之中會用到大量的記憶體,則可以用@autoreleasepoll{…}包起來
    缺點:速度會慢一些
    優點:記憶體較好(在ios裡面,記憶體較重要)
  5. strong與weak的差別:變數的宣告值strong代表這個變數會增加retain的值,而weak則不會。
    weak比較像依賴的關係,當今天主要strong的變數被刪除了,weak裡的值也會變為空值。
    而strong則會增加retain的值,主要變數被刪除了,因為retain還是大於1,所以變數的記憶體並不會被釋放。(要小心Memory leak)
Posted on

上課筆記(三) – Operation、Delegation、基本類別介紹

Operation

  1. 取得class資料的相關變數
    Class me = [obj class];
    NSString * name = [obj className];
    //判斷是否繼承於UIView
    if( [ obj isKindOfClass:[UIView class] ] ){
    NSLog(@"obj繼承於UIView");
    }
    //判斷是否是這個class的實體
    if( [ obj isMemberOfClass: [NSString class] ] ){
    NSLog(@"obj的類別是NSString");
    }
  2. 確認兩個變數指向同一個記憶體位置
    if(obj1 == obj2) {}

    確認兩個實體的值相同

    if([obj1 isEqual: obj2]){//使用者可自行在class裡面新增此一函數,來決定該如何判別兩個類別相同}
  3. 呼叫物件的描述,回傳字串 [obj description];//等於NSLog(@”%@”,obj);

Delegation

  1. 定義:物件要完成某件行為時利用別人定義好的某項功能來完成。
    所以專案第一個被呼叫的應該是Delegate裡的

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. xcode專案的main.m
    #import ㄑUIKit/UIKit.h;
    
    #import "AppDelegate.h"
    
    int main(int argc, char *argv[])
    {
      @autoreleasepool {
           //argc:在argv裡元素的個數,通常對應main的參數
           //argv:一串輸入值
           //UIApplication或其子類別實體的class name,如果值是nil則會認為是UIApplication。
           // NSStringFromClass([AppDelegate class] 系統做完事後要通知誰
           return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }

基本類別

  1. NSObject:最基本的物件
    [obj className];//自我檢視
    [obj isEqual:obj2]//物件比較
  2. NSString
    [NSString stringWithFormat:@"It is %@",@"Tom"];//格式化字串
    //常用method
    str=[str stringByAppendingString:"abc"];//加字串在尾端,會回傳str
    str=[str stringByAppendingFormat:"name %@",@"Tom"];//加格式化字串在尾端,會回傳str
    BOOL equ = [str isEqualToString:str2];//字串相同
    //比較兩字串相同的方法
    if([str compare:str2 options:NSLiteralSearch]){}
    if([str idEqualToString:str2]){
    //字串搜尋
    NSRange range = [str rangeOfString:str2];
    NSLog(@"str2位於str1的第%d的位置,長度為%d",range.location,range.length);
  3. NSMutableString:可在原本字串之間插字串(用insertString)
    NSMultableString *str = [NSMultableString string];
    [str appendString:@"test"];
    [str insertString:@"hello" atIndex:1];
    NSLog(str);//ThrlloEST
  4. Set:無順序性的集合,資料有惟一性(物件要比較是否相同須覆寫isEqual和hash)
    NSMutableSet:queue的概念,用在List把移出畫面的東西暫存。
    NSOrderedSet:依照加入的順序排(比起NSMutableSet)
    相關網頁:
    http://stackoverflow.com/questions/6545722/help-with-isequals-and-hash-in-iphone
  5. Array:有順序性的集合,當資料從中間刪除,剩的index會自動往前補。
    NSArray: 不可新增修改的array。
    NSMutableArray:可新增修改,保證是0,1,2,3的index不會跳號。
  6. Dictionary:存在key-value型式資料的集合
    NSDictionaryNSMutableDictionary
  7. 走訪所有元素的寫法
    for(NSString *ele in array){
           NSLog([ele description]);
    }
  8. NSNumber:才可以丟進set或array裡
  9. NSNull:為了要丟進array裡面,因舊式寫法array宣告nil代表尾端,所以要丟空值要改丟NSNull
  10. Scalar:把物件當陣列般存取。例:
    Car * car = [car new];
    
    car[1] = @"name"; //寫入scalar
    NSLog(@"%@",car[1]);//讀取scalar
    
    car[@"dict"] = @"value";//寫入object
    NSLog(@"%@",car[@"dict"]);//讀取object

    要注意的是,如果我們呼叫car[1]代表執行下面兩個函數而不代表真的是array

    - (id) objectAtIndexedSubScript:(NSInteger) index {
      return @"Car";
    }
    -(void) setObject:(id)thing atIndexedSubscript:(NSInteger) index{
       //在此設定index為index的值為thing
    }

    如果果們呼叫car[@”dict”]則是執行下面兩個函數

    -(id) objectForKeyedSubscript:(id)key{
        return @"dict";
    }
    -(void) setObject:(id) thing forKeyedSubscript:(id<nscopying>) key{
         //在此做設定
    }
Posted on

上課筆記(二) – Objective-C語言介紹、物件存取

Objective-C語言

  1. @代表物件
    [@”Hello world”] => 方括弧是存取物件裡的方法
    例:

    NSString * str =@"World";
    str = [NSString stringWithFormat:@"Hello"];
    NSLog(@"str is: %@",str);
  2. Class:類別
    Object:物件及實體,包括
    (a) 名字(Name)
    (b) 屬性(State):field, attribute, member, 屬性, 狀態, 成員
    (c) 行為(Behavior):method, action, member function
    Message:使用方來傳遞訊息。例:NSString的StringWithString
    螢幕快照 2013-08-02 下午5.49.59
    PS: 若在#import <Foundation/Fundation.h>下面加上@Class Car;,代表把Car當作class,在.m檔才import。
  3. self(存取自己),只能用在implementation的『{』至『@end』之間。
  4. variable宣告:
    NSString * name = [[NSString alloc] init];
  5. 宣告時,前方的+或-代表是否要透過init alloc來回傳物件。
    +號是不用透過init alloc傳回物件
  6. 要公開(public)的放在.h,不公開的放在.m
  7. NSStrung * name = [[NSString alloc] init];
    等同於 NSString * name = [NSString new];
    =>配置記憶體與初始化是產生物件後的第一個動作
  8. Obj C可以使用id去動態新增method,所有obj c的語言都會被編譯成c語言。

Message Syntax

  1. 『物件.xxx』所存取的不是屬性,而是方法。是存取物件裡面的getter和setter。
    label.text = @"Description"; //等於 [label setText:@"Description"];
    NSString *str = label.text; //等於 NSString*str = [label text];
  2. 自動產生getter和setter
    @property int age; //會自動幫我們產生getter和setter
    @property (strong) NSString * name; //如果是物件,前面要加strong或weak
  3. 如果interface和implementation在同個檔案,在interface裡用@property,在implementation裡需加上@synthesize
    @synthesize age;//自動產生的變數名稱會是_age

    若分開為.h及.m檔,則.h檔宣告後,.m檔裡不用寫就會自動產生。

  4. 動態型別 – id:任何繼承NS Object的物件型別,宣告方式如下
    id someObject; //不用加*號 ( <s>id * someObj</s> )

    用法例子:在apple在view事件觸發時要接收事件,會希望任何class都可以去接收該事件都可以。
    當不知道是誰接收時,就會用id去宣告

  5. 空指標nil,物件型別的空值,等同於NULL。若將nil丟給方法則會像石沉大海一樣什麼都不發生也不會有error。=>經指正會產生空值error
  6. Obj C的BOOL是傳YES(true)及NO(false)。
  7. 要判斷現在的class裡是否有某個函數要用Selector,回傳的型別是SEL。使用範例如下
    -(void)methodWithNoArguments;
    SEL noArgumentSelector = @selector(methodWithNoArguments);
    
    -(void)methodWithOneArgument:(id)argument;
    SEL oneArgumentSelector = @selector(methodWithOneArgument:); // notice the colon here
    
    -(void)methodWIthTwoArguments:(id)argumentOne and:(id)argumentTwo;
    SEL twoArgumentSelector = @selector(methodWithTwoArguments:and:); // notice the argument names are omitted

    Selectors are generally passed to delegate methods and to callbacks to specify which method should be called on a specific object during a callback. For instance, when you create a timer, the callback method is specifically defined as:

    -(void)someMethod:(NSTimer*)timer;

    So when you schedule the timer you would use @selector to specify which method on your object will actually be responsible for the callback:

    @implementation MyObject
    
    -(void)myTimerCallback:(NSTimer*)timer
    {
        // do some computations
        if( timerShouldEnd ) {
          [timer invalidate];
        }
    }
    
    @end
    
    // ...
    
    int main(int argc, const char **argv)
    {
        // do setup stuff
        MyObject* obj = [[MyObject alloc] init];
        SEL mySelector = @selector(myTimerCallback:);
        [NSTimer scheduleTimerWithTimeInterval:30.0 target:obj selector:mySelector userInfo:nil repeats:YES];
        // do some tear-down
        return 0;
    }

    In this case you are specifying that the object obj be messaged with myTimerCallback every 30 seconds.
    假如一個function在該做的事完成後要執行selector callback,可以類似下面這樣寫

    -(void) someMethod:(id)handler selector:(SEL)selector {
        // some codes here...
    
        // execute callback function
        if( handler != nil &amp;&amp; selector != nil &amp;&amp; [handler respondsToSelector:selector] ) {
            [handler performSelector:selector];
        }
    }

    來源:http://stackoverflow.com/questions/297680/how-do-sel-and-selector-work-in-iphone-sdk

  8. 判斷class是否有該函數使用
    if([obj respondsToSelector:action]) { ... }
Posted on

上課筆記(一) – 專案運作流程、c語言概論、指標與物件

課程資訊

  1. 上課教師:潘聖文 Michael Pan ( scentsome@gmail.com) > 認真好老師推!
  2. 課程名稱:資策會IPhone應用軟體開發入門篇

運作流程

  1. main function為固定進入點
  2. 在iphone app開發裡面,一個一整頁的畫面是Scene,會有對應一個Controller
  3. 切換不同Scene的叫做View Controller,跳出如輸入框或選取框的這種(非整頁切換),則不需View Controller
  4. Navigation Controller是只有上面的Bar(用以控制頁面切換),會將View Controller塞進裡面。
  5. 所有Object特有的類別都會加上NS開頭(因為是某個縮寫為NS的公司開發的)
  6. Objective-C可以在執行時動態產生Code。
  7. 整個Design Flow圖如下
    螢幕快照 2013-08-02 下午4.18.20

開始之前

    1. 變數:代表記憶體的編號,型別決定占記憶體多大的位置,變數則是存放記憶體起始位置。
      NSLog(@"%d",varA); //只要是OBJ C型別的東西都要加@來存取(物件則用%@)
    2. Function宣告
      cal(int a, int b);
      int main(int argc, const char * argv[]){
        int a=5;
        float b=6;
        cal(a,b); //呼叫函數
        return 0;
      }
      cal(int a,int b){
        printf("a+b=%d",(a+b));
      }
    3. ios程式的基本組成是由三個frameworks:
      (a) UIKit:給特殊樣式的ui
      (b) Core Graphics:畫圖
      (c) Foundation:C和OBJ C用的
      ps:要自己加可以按Target=>Summary=>Linked Frameworks and Libraries=>+
    4. 副檔名:表頭檔.h和內容檔.m及.mm(要用view一定要用.m;要像視訊則可用.mm)

Pointer & Object 指標與物件

  1. Pointer在C裡面代表存放的是一個記憶體位置
    int a = 5;
    int * pa;//因此所有obj c裡面所有的物件,只要他是存放記憶體位置,都需要用指標型態去寫
    pa = &amp;a;//放的是一個記憶體位置
  2. Struct是型別,也就是class(類別)
    struct Date{
       int day;
       int month;
       int year;
       void ( * formatedDate ) (struct Date date);
    }
    void formatedFunction(struct Date date){
       printf("The day is %d, %d/%d",date.year, date.month, date.day);
    }
    struct Date date = {3,10,1970};
    today.formatedDate = formatedFunction;
    today.formatedDate(today);
  3. Function是存放動作,其記憶體是存在stack裡
  4. 所以Objective C程式的記憶體位置配置這樣的
    螢幕快照 2013-08-02 下午5.01.06
    Stack的部份是不用管理的,因為用完就沒了,而在Object C裡需要去做記憶體管理的部份則為Heap的區塊。
    所以當我們在Obj C裡宣告了某個物件,必需用

    a = malloc(sizeof(int));//會產生在heap,產生記憶體位置,可做記憶體管理。
  5. Static variable(靜態變數),會放在Data Segment。
  6. 所有的View Object都會對應到一個型別(Custom Class那邊去設定)
    螢幕快照 2013-08-02 下午5.17.09
Posted on

使用Flex編譯出ios的ipa檔案

這邊提供一些我看到的教學影片及連結

1.在Windows上一步步發佈的方式

http://support.brightcove.com/en/docs/step-step-guide-publishing-apple-app-store-using-windows

2. 使用Flex編出ipa的教學

http://tv.adobe.com/watch/adc-presents/build-ios-applications-using-flex-and-flash-builder-45/

3. 怎麼在windows上產生.p12檔案

4. 在Flex裡安裝AIR SDK的方式

http://helpx.adobe.com/flash-builder/kb/error-run-debug-deploy-ios.html

http://www.flashdeveloper.co/post/10985842021/overlay-adobe-air-32-in-flash-builder-46

其實最基本的可以就依照這篇文章去做一步步的發佈設定

如果不想太快買開發者身份 也可以到google 打上fake .p12 ,下載破解檔案

就可以直接做發佈的設定了!

===================================

另外也提供不使用flex去做發佈的方式

1.安裝 adobe AIR SDK,請將以下壓縮檔,解到自己電腦任意目錄中

 http://www.adobe.com/devnet/air/air-sdk-download.html

例如,我電腦中,我解到:E:\software\AdobeAIRSDK

 

2.準備 command line 批次檔 build.bat,檔案內容如下:

 

set SDK_HOME=E:/software/AdobeAIRSDK à 換成你放 air sdk 的位置

set ADT_JAR=%SDK_HOME%/lib/adt.jar

 

set APP_NAME=HorseRacingDemo à 換成你專案的名稱,會用來找對應的 xxx.swf 與 xxx-app.xml,並發布成 xxx.ipa

set APP_ROOT_DIR=C:/Users/ben.chang/Desktop/新增資料夾 à 所有東西放置的資料夾

set BUILD_DIR=%APP_ROOT_DIR%

set APP_ROOT_FILE=%APP_NAME%.swf

set APP_DESCRIPTOR=%APP_NAME%-app.xml

set IPA_NAME=%APP_NAME%.ipa

set STORETYPE=pkcs12

set KEYSTORE=FakeCert.p12

set STOREPASS=1234

set PROVISIONING_PROFILE=Fake.mobileprovision

 

java -jar %ADT_JAR% -package -target ipa-debug -provisioning-profile %APP_ROOT_DIR%/%PROVISIONING_PROFILE% -storetype %STORETYPE% -keystore

 

%APP_ROOT_DIR%/%KEYSTORE% -storepass %STOREPASS% %APP_ROOT_DIR%/%IPA_NAME% %APP_ROOT_DIR%/%APP_DESCRIPTOR% -C %BUILD_DIR% %APP_ROOT_FILE%

 

pause

 

3.準備 xxx-app.xml

 

我的 Flash CS 5.0,設定輸出 ipad 產出的 xml 為:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no” ?>

<application xmlns=”http://ns.adobe.com/air/application/2.0“>

<id>no-name</id>

<version>1.0</version>

<filename>?芸??1</filename>

<description/>

<name>?芸??1</name>

<copyright/>

<initialWindow>

<content>?芸??1.swf</content>

<systemChrome>standard</systemChrome>

<transparent>false</transparent>

<visible>true</visible>

<fullScreen>false</fullScreen>

<aspectRatio>portrait</aspectRatio>

<renderMode>auto</renderMode>

<autoOrients>false</autoOrients>

</initialWindow>

<icon/>

<customUpdateUI>false</customUpdateUI>

<allowBrowserInvocation>false</allowBrowserInvocation>

<iPhone>

<InfoAdditions>

      <![CDATA[<key>UIDeviceFamily</key><array><string>2</string></array>]]>

    </InfoAdditions>

</iPhone>

</application>

 

設定輸出 iphone 的 xml 為:

 

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no” ?>

<application xmlns=”http://ns.adobe.com/air/application/2.0“>

……

……

<iPhone>

 <InfoAdditions>

      <![CDATA[<key>UIDeviceFamily</key><array><string>1</string></array>]]>

    </InfoAdditions>

</iPhone>

</application>

 

設定輸出 iphone 與 ipad 的 xml 為:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no” ?>

<application xmlns=”http://ns.adobe.com/air/application/2.0“>

……

……

<iPhone>

 <InfoAdditions>

      <![CDATA[<key>UIDeviceFamily</key><array><string>1</string><string>2</string></array>]]>

    </InfoAdditions>

</iPhone>

</application>

 

4.資料夾中準備好相關檔案:

 

l   xxx.swf

l   xxx-app.xml

l   build.bat

l   FakeCert.p12

l   Fake.mobileprovision

 

譬如,我在自己電腦桌面上開一新資料夾,如下畫面:

執行 build.bat 大約一兩分鐘 就可產出 *.ipa

 

Posted on

外行人也能學會的App企劃法

最近買了這本書:
http://buy.yahoo.com.tw/gdsale/gdbksale.asp?gdid=3639539

這本書在第一張的地方,先說出App與一般的電腦程式最大差異點在於『行動性』。
因此好的APP應具備下面幾個特質:

1. 簡單上手
2. 目的單純(一次做一件事)
3. 流暢度和穩定度

在做APP之前要先問自己下面幾個問題:

1. 為什麼要做APP而不是網站,找出做APP的意義。
2. 然後找出APP要扮演的角色,是附屬在某個服務如dropbox,或是一個獨立的服務如Line、或者是一個行銷、廣告的工具。
3. 預期這支APP可以解決什麼問題?
4. 鎖定目標族群
5. 產品所能帶來的效益

在企劃自己的APP之前,應要多去看別人的APP,以下面幾項去切入剖析

1. 是否有善用行動裝置的特性,提供一般網站無法滿足的訴求
2. 這隻APP鎖定的是那一些族群? 提供了那些主要資訊或活動?是否可以一眼吸引目標族群?所提供的功能是否符合族群功能?
3. UI是否清楚明瞭? 操作動線是否流暢?
4. 製作邏輯剖析

我們應該要多去了解市場現有的APP的狀況,或是排行榜上榜的APP遊戲,並學習用上面的觀點去剖析該APP,培養自己對於這個市場的敏銳度,從觀察中找創意。並且應善用情境想像和角色模擬,找出問題點。

在UI與動線規劃上,要了解手機動線是3D的,並且在設計上許多內容是在套入程式之後才會套入,因此程式師必須與美術設計者有較密切的溝通,才能確保美編產生的東西可以使用在程式內。在美術設計上,應該以『好用』為主要訴求。

在上架前我們則需要準備下列東西:

1. 名稱:在Iphone裡最長六個字、app store最長10個字
2. 主icon:應醒目、可表現主題
3. 截圖:以五張為限,應盡量抓可凸顯APP特色的圖
4. 文案:建議用條列式的將內容和主要功能強調出來,並加強特色介紹,讓使用者一目了然。
5. 關鍵字:盡可能把所有的關鍵字都列出來,或者也可以參考競品的APP介紹,將有用的關鍵字納入,增加APP被搜尋到的機會
6. 上架日期:若送審過後要出現在APP Store的日期