2011年9月27日火曜日

UIImageの生成の仕方

UIImageの生成にあたり、簡単なので[UIImage imageNamed:@"image.png"]といった具合に生成することもあるかと思いますが、この場合マルチタスクで一旦プログラムが終了すると、情報が廃棄されてしまいます。

そのため、やはり面倒でも以下のような生成をしないとだめなようです。

   NSString *path= [[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"];
   UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];


2011年9月25日日曜日

MKAnnotationのキューを使うと拡張プロパティが壊れる

MKMapKitではTableViewと同じく、MKAnnotationをキューに入れて使い回すことができます。ただし、MKAnnotationを派生させて追加のプロパティを入れていると、値が壊れてしまうことがあるようです。

そのため、キューをはずして都度Map上に持って行くことにしましたが、あってるのかな?

皆困っていないのだろうか・・

2011年9月19日月曜日

地図の表示(MapKit)

MapKitはメルカトル図法をサポートする。

MapKitは3つの座標系をサポートする。

1. 地図座標(球状表現の緯度/経度)
座標 CLLocationCoordinate2D (緯度と経度)
領域 MKCoordinateSpan  及び MKCoordinate Region

2. 地図点(メルカトル図法のX、Y)
地図点 MKMapPoint
領域 MKMapSize,  MKMapRect

3. 点(UIView)
カスタムコンテンツの描画前に点にマッピングされる必要がある。
  点:CGPoint
     領域:CGSize, CGRect


座標系の変換

地図座標
convertCoordinate: toPointToView: (MKMapView) 
convertRegion: toRectToView: (MKMapView)
地図座標
地図点
MKMapPointForCoordinate
地図点
地図座標
MKCoordinateForMapPoint
MKCoordinateRegionForMapRect
地図点
pointForMapPoint: (MKOverlayView) 
rectForMapRect: (MKOverlayView)
地図座標
convertPoint: toCoordinateFromView: (MKMapView) 
convertRect: toRegionFromView: (MKMapView)
地図点
mapPointForPoint: (MKOverlayView) 
mapRectForRect: (MKOverlayView)

MKMapView.regionの構造体であるMKCoordinateRegionのスパン(span)は矩形の幅と高さの値 に似ているが、地図座標で指定されるため、単位は度、分、秒となる。

緯度1度は約111キロメートルに相当するが、経度の長さは緯度によって変わる。赤道では、経度1度は約111キロメートルに相当するが、極ではゼロになる。スパンをメートル単位で指定したい場合は、 MKCoordinateRegionMakeWithDistanceを使用して、度数ではなくメートル値で領域データ構造体 を作成する。

位置を変更するには、centerCoordinateプロパティを設定するか、[mapView setCenterCoordinate:centerCoordinate animated:YES];等で指定する。

領域割り当てる場合は、regionプロパティを設定するか、[mapView setRegion:region animated:YES];等で指定する。

// 縮小する

MKCoordinateRegion theRegion = myMapView.region;
theRegion.span.longitudeDelta *= 2.0; 
theRegion.span.latitudeDelta *= 2.0; 
[myMapView setRegion:theRegion animated:YES]; 


地図上でのユーザの現在位置表示:
mapView.showUserLocation = YES;

MKUserLocation注釈オブジェクトが地図に追加されると、カスタム注釈が追加されたときと同様 にデリゲートによってそのことが報告されます。カスタム注釈ビューをユーザの位置に関連付けた い場合は、デリゲートオブジェクトのmapView:viewForAnnotation:メソッドからそのビューを返 す必要があります。デフォルトの注釈ビューを使用する場合は、このメソッドからはnilを返す必 要があります。 

地図に対するユーザの対話操作への応答:
MKMapViewDelegateプロトコルに準拠したオブジェクトで次の種 類のイベントに応答する。
■ 地図の可視領域の変更
■ ネットワークからの地図タイルの読み込み
■ ユーザの位置の変更
■ 注釈とオーバーレイに関連する変更

地図の注釈:
地図に固定のコンテンツを追加して地図と一緒にスクロールさせたい場合は、注 釈とオーバーレイを作成しなければなりません。 



地図に注釈を表示するには、アプリケーションは2つのオブジェクトを指定する必要があります。
  • MKAnnotationプロトコルに準拠し、注釈のデータを管理するオブジェクト(注釈オブジェク ト)。
  • 地図の表面に注釈の可視表現を描画する(MKAnnotationViewクラスから派生した)ビュー(注 釈ビュー)。 


注釈ビューを提供するにはMap Viewデリゲートオブジェクトを使用します。
1. 注釈オブジェクトの定義
MKPointAnnotationクラス(タイトル、サブタイトル)またはMKAnnotationプロトコルに準拠したカスタムオブジェクト

2. 注釈ビューの定義
静止画像の場合、MKAnnotationViewクラスのimageプロパティに画像を割り当てる。
ピンの場合、MKPinAnnotationViewクラスを使用する。
それ意外の場合、MKAnnotationViewクラスをサブクラス化する。

3. MapViewデリゲートにmapView:viewForAnnotation:メソッドを実装する。
既存の注釈ビューをキューから取り出し、なければ新規の注釈ビューを作成する。

4. addAnnotation: またはaddAnnotationsでMapViewに注釈オブジェクトを追加する。

間引いた注釈の追加、または追加した注釈の間引きディベロッパ自身が対応しなくてはならない

静止画像の実装例:

MKAnnotationView* aView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
                                  reuseIdentifier:@"MyCustomAnnotation"] autorelease];
aView.image = [UIImage imageNamed:@"myimage.png"];
aView.centerOffset = CGPointMake(10, -20);

標準的な注釈ビューは、デリゲートのmapView:viewForAnnotation:メソッドで作成します。

注釈ビューが必要になると、Map ViewはそのデリゲートオブジェクトのmapView:viewForAnnotation: メソッドを呼び出します。 nilを返す場合、ピン注釈ビューが使用される。ピン注釈ビュー以外を使用する場合、使用するビューをそこで作成する。


AnnotationはTableViewと同じくキューに入れて表示させることもできる
(地図の倍率が変わらない場合、該当する)


- (MKAnnotationView *)mapView:(MKMapView *)mapView
                      viewForAnnotation:(id <MKAnnotation>)annotation
{
//
これがユーザの位置の場合は、単にnilを返す
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// カスタム注釈を処理する
if ([annotation isKindOfClass:[MyCustomAnnotation class]])
{
//
まず、既存のピン注釈ビューをキューから取り出すことを試みる 
MKPinAnnotationView* pinView = (MKPinAnnotationView*)[mapView
dequeueReusableAnnotationViewWithIdentifier:@"CustomPinAnnotationView"];
        if (!pinView)
{
//
既存のピン注釈ビューが利用できない場合は、新しいビューを作成する
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"CustomPinAnnotation"]
                             autorelease];
            pinView.pinColor = MKPinAnnotationColorRed;
            pinView.animatesDrop = YES;
            pinView.canShowCallout = YES;
// 詳細ディスクロージャボタンを吹き出しに追加する 
   UIButton* rightButton = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
            [rightButton addTarget:self action:@selector(myShowDetailsMethod:)
                               forControlEvents:UIControlEventTouchUpInside];
            pinView.rightCalloutAccessoryView = rightButton;
        }
        else
            pinView.annotation = annotation;
        return pinView;
    }
return nil; 

注釈オブジェクトの間引き:
mapView:regionWillChangeAnimated:メソッドと mapView:regionDidChangeAnimated:メソッドを実装して、地図の拡大縮小レベルの変更を検出する。 

iOS ユーザ位置の取得

iOSでユーザ位置の取得をするには、Core Location フレームワークを使用します。

Core Location フレームワークでは、電話基地局、Wifiポイント、GPSを利用してすべてのデバイスで位置を取得することができます(「標準位置情報サービス」)。

その他に、省電力で位置の取得と変更の通知を受けることのできる「大幅変更位置情報サービス」、境界線の横断を検知できる「領域観測」があり、これらはiOS4以降でサポートされます。
(定期更新が必要な場合、できるだけ「大幅変更位置情報サービス」を使用する。)

実装にあたっては、CoreLocation.frameworkをTargetのBuild PhasesのLink Binary With Librariesから追加します。また、ヘッダファイルに、#import <CoreLocation/CoreLocation.h>を追加します。

<必要に応じ、Info.plistにUIRequiredDeviceCapabilitiesを追加し、location-servicesを指定もしくはGPSのみの場合、gpsを追加するが、位置情報サービスがなくても動作する場合は指定をしない>


以下により実装する。
1.位置情報サービスの利用可否の確認
CLLocationManagerのlocationSercicesEnabledメソッドを呼び出す(iOS4)
    YESの場合、開始可能。NOの場合、位置情報サービスを開始しようとすると位置情報サービスを有効にするかどうかユーザに確認を求めてくる。

 if ([CLLocationManager locationServicesEnabled]) {

}
else {

}

2.大幅変更位置情報サービスの開始
if(locationManager == nil){
          locationManager = [[CLLocationManager alloc] init];
     }
    locationManager.delegate = self;
    [locationManager startMonitoringSignificantLocationChanges];

3.サービスからの位置データの受信
  デリゲートによる場合:
     -(void)locationManager:(CLLocationManger *)manager
       didUpdateToLocaton:(CLLocaton *)newLocation
       fromLocation:(CLLocation *) oldLocation{

        NSDate* eventDate = newLocation.timestamp;
        NSTimeInterval howRecent = [eventDate timeIntervalSiceNow];
        if (abs(howRecent) < 15.0) {
            // 新しいイベントでは更新をOFFにする?           
       }
      newLocation.coordinate.latitude ....
      newLocation.coordinate.longitude .....
    }

デリゲートによらない場合
locationManager.location  (CLLocation *)  //位置
    locationManger.heading (CLHeading *)  //方位

   location.coordinate (CLLocationCoordinate2D)  // 座標
       coordinate.latitude // 緯度 (double)
      coordinate.longitude  // 軽度 (double)

    その他、高度、精度、タイムスタンプ、スピード、コース等が得られる。

4. 位置情報の反映
   [mapView setCenterCoordinate:locationManager.location.coordinate animated:YES];


5. サービスの停止
   [locationManager stopMonitoringSignificantLocationChanges];

うぉ、動いたな。

2011年9月15日木曜日

iAdの収入が不安定化

iAdの収入が不安定化してきているのは、今回は恐らく低迷の兆しだ。

2011年7月28日木曜日

複数のオブジェクトでデータを共有する

Objective-Cで複数のオブジェクトでデータ(インスタンス)を共有するためには、デザインパターンとしてシングルトンを採用する。

シングルトンでは、当該データ(インスタンス)がなければ生成し、あれば現状(インスタンス)を維持するオブジェクトの生成(インスタンス化)のための+メソッドとその状態を保持するStatic変数を実装することで、インスタンスの取得指示で一つのインスタンスのみを操作することができるため、そのインスタンスを複数のオブジェクトで共有することができる。

シングルトンの実装方法

SingletonManager.h
@interface SingletonManager : NSObject {
       NSInteger managedParam;
}
@property NSInteger managedParam;
+ (id)sharedManager;
@end

SingletonManager.m
static id theSharedManager = nil;

@synthesize managedParam;


+ (id)sharedManager {
 if (theSharedManager == nil) {
 theSharedManager = [[self alloc] init]; }
 return theSharedManager;
}

- (id)init
{ self.managedParam=0; return self; }

- (void)dealloc { [super dealloc]; }



シングルトンの利用方法

SomeClass.m
#import "SingletonManager.h"
.....
SingletonManager *single =
[SingletonManager sharedManager];
single.managedParam=100;


明示的な初期化と開放

SingletonSampleAppDelegate.m
#import "SingletonManager.h"

- (void)applicationDidFinishLaunching:...
(void)[SingletonManager sharedManager];
}

- (void)dealloc {
 SingletonManager *single =
[SingletonManager sharedManager];
[single dealloc];
}


にゃーるへそ。

http://ylb.jp/iOSDev/SingletonSample.pdf

2011年7月16日土曜日

データソースクラスを分離する

iPhoneAppに限らず、基本はビュー、ビューコントローラ、データソースの3層構造でシステムを作るのは常識だ。

しかしながら、iPhone Appの解説本を見ても、Appleが提供しているひな形をベースにUIKitを無秩序に組み込むプログラム例が多く、あまり参考にならない。

とりあえず、基本となるplistでのファイル格納クラスを分割してみた。なお、初期のロード時にバージョンアップメッセージを表示し、ユーザに新しい機能を伝える必要があるため、バージョン情報を保管し、データロード時にバージョンが異なる場合、新機能の通知をロードメソッドに実装する。

*.h
NSObjectから派生して作ればいい。
基本は、母体となるメインのビューコントローラから参照するアドレスまたはポインターをプロパティ宣言する。
また、データソースのクラスであるため永続化のためのsaveメソッド、及び読み出すためのloadメソッドを宣言する。


#import <Foundation/Foundation.h>
@interface SetupData : NSObject {
NSString *adress;
NSString *subject;
double VAT;
BOOL soundON;
double volume;
}
@property (nonatomic, retain) NSString *adress;
@property (nonatomic, retain) NSString *subject;
@property double VAT;
@property BOOL soundON;
@property double volume;

-(void)load;
-(void)save;


@end


*.m
プロパティ宣言をしたクラスをシンセサイズし、外部に提供するloadメソッド及びsaveメソッドを実装する。

なお、ファイルのディレクトリを取得するメソッドも内部用に実装したほうがいい。


#import "SetupData.h"
ここでファイル名を定義する。
#define settingFileName @"setting.plist"


@implementation SetupData
@synthesize adress, subject, VAT, soundON, volume;


共通的なメソッドとして、ディレクトリを取得するメソッドを実施しておく。

- (NSString *)settingFilePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:settingFileName];
}


loadメソッドを実装する。
-(void) load{
NSString *VATstring = [[NSString alloc] init];
NSNumber *number = [[NSNumber alloc]init];
NSNumber *volumeSwitch = [[NSNumber alloc] init];
NSString *version = [[NSString alloc]init];

NSString *notSettingBundle = [self settingFilePath];
NSDictionary *dictionary = [[NSDictionary alloc]initWithContentsOfFile:notSettingBundle];


ファイルがない場合、dictionaryはnilとなる。ファイルがある場合のみディクショナリの内容を読み込む。

if (dictionary != nil) {
adress = [[dictionary objectForKey:@"adress"]retain];
subject = [[dictionary objectForKey:@"subject"]retain];
VATstring = [[dictionary objectForKey:@"VAT"]retain];
number =  [[dictionary objectForKey:@"volume"]retain];
volumeSwitch = [[dictionary objectForKey:@"switch"]retain];
version = [[dictionary objectForKey:@"version"]retain];
}

ファイルがない場合はデフォルト値を実装する。
if (adress == nil) {
adress = [[NSString alloc] initWithString:@""];
}
if (subject == nil) {
subject  = [[NSString alloc] initWithString:@"Roll Paper Calculator"];
}

数値の場合、NSNumberもしくはNSStirngで格納しなくてはならないため、読み込み時に逆変換する。
if (VATstring == nil) {
VAT = 0.05;
}
else {
VAT = (double)[VATstring intValue];
VAT = VAT / 100.0;
}
if (number == nil) {
volume = 0.2;
}
else {
volume = [number doubleValue];
}
if (volumeSwitch == nil) {
soundON = YES;
}
else {
soundON = [volumeSwitch boolValue];
}

新規導入時、もしくはバージョンアップ時のメッセージを表示する。初回以降は表示されない。
if (version == nil || ![version isEqualToString:@"4.18"] ){
  UIAlertView *alertView = [[UIAlertView alloc
initWithTitle:@"Version 4.18"
message:@"Internal Design Renewal. Save volume off state whent App end"            
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
  [alertView show];
  [alertView release];
}


一時オブジェクトを解放する。
[version release];
[number release];
[VATstring release];
[dictionary release];

}

-(void)save{

保存のためのディクショナリを確保する。
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc]init];
[dictionary setObject:adress forKey:@"adress"];
[dictionary setObject:subject forKey:@"subject"];

数値データはNSNumberまたはNSStringに変換してディクショナリに格納する。
[dictionary setObject:[[NSNumber numberWithInt:(int)(VAT*100.0)] stringValue] forKey:@"VAT"];
[dictionary setObject:[NSNumber numberWithDouble: volume] forKey:@"volume"];
[dictionary setObject:[NSNumber numberWithBool: soundON] forKey:@"switch"];
[dictionary setObject:@"4.18" forKey:@"version"];

ディクショナリを所定のファイルに格納する。
[dictionary writeToFile:[self settingFilePath] atomically:YES];

ディクショナリを解放する。
[dictionary release];
}

@end



以上です。

NSNumber

NSDictionaryやNSArrayで数字やBOOLを扱う場合、NSNumberを使用します。

BOOL型の変数からNSNumberオブジェクトを作りたい - initWithBool:
int型の整数からNSNumberオブジェクトを作りたい - initWithInt:
float型の変数からNSNumberオブジェクトを作りたい - initWithFloat:
double型の変数からNSNumberオブジェクトを作りたい - initWithDouble:

(注)一時的なオブジェクト生成の場合、[Number numberWith... : ...]; とする。

NSNumberオブジェクトからBOOL型の変数を作りたい - boolValue:
NSNumberオブジェクトからint型の整数を作りたい - intValue:
NSNumberオブジェクトからfloat型の変数を作りたい - floatValue:
NSNumberオブジェクトからdouble型の変数を作りたい - doubleValue:
NSNumberオブジェクトをNSString(文字列)に変換したい - stringValue;
NSNumberオブジェクト内の値が他のNSNumberオブジェクトと同じか知りたい - isEqualToNumber:

詳細はこちらに記載があります。
http://konton.ninpou.jp/program/cocoa/dataobject/nsnumber.html


2011年6月30日木曜日

テーブルのセルの高さを変える。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Return height the height of cell(Row)
return 35.0;
}

テーブルのセクションタイトルの文字色を変更する。

テーブル(UITableView)のセクションタイトルは、以下の記述ではデフォルトの文字色から変更することはできません。


-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (section == 0) {
return @"E-mail";
}
else if (section == 2){
return @"Sound";
}
else {
return @"Value Added Tax (VAT)";
}
}

そこで以下の記述とすると、セクションタイトルにビューを返すことができ、背景を黒とし、文字の色を白くすることができます。

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
if (section == 0) {
UIView *v = [[UIView alloc] init];
v.backgroundColor = [UIColor blackColor];
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 30.0f)];
UIImage *bgImage = [UIImage imageNamed:@"topTableSectionTitleBack.png"];
lbl.backgroundColor = [UIColor colorWithPatternImage: bgImage];
lbl.textColor = [UIColor whiteColor];
lbl.text = @" E-mail";
[v addSubview:lbl];
[lbl release];
return v;
}
else if (section == 2){
UIView *v = [[UIView alloc] init];
v.backgroundColor = [UIColor blackColor];
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 30.0f)];
UIImage *bgImage = [UIImage imageNamed:@"topTableSectionTitleBack.png"];
lbl.backgroundColor = [UIColor colorWithPatternImage: bgImage];
lbl.textColor = [UIColor whiteColor];
lbl.text = @" Sound";
[v addSubview:lbl];
[lbl release];
return v;
}
else {
UIView *v = [[UIView alloc] init];
v.backgroundColor = [UIColor blackColor];
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 30.0f)];
UIImage *bgImage = [UIImage imageNamed:@"topTableSectionTitleBack.png"];
lbl.backgroundColor = [UIColor colorWithPatternImage: bgImage];
lbl.textColor = [UIColor whiteColor];
lbl.text = @" Value Added Tax (VAT)";
[v addSubview:lbl];
[lbl release];
return v;
}
}

しかしながら、このままではセクションのテーブルがタイトル文字と被ってしまいます。そこでテーブルのプロパティにあるHedderのサイズを30とするならば、かぶりを解消することができます。気づくのに結構な時間を費やしてしまった。

2011年6月26日日曜日

UIViewControllerを分割する

UIが複雑になってくるとUIViewControllerが非常に巨大になってきて困っている方も多いのではないでしょうか。
そのような場合には以下の方法があります。
・再利用可能なUIView部品を作成し、コントロールの一部を組み込む。
・UIViewControllerをオブジェクト分割する

再利用可能なUIView部品の作成方法については下記にあるため参考とされたい。ここでのContrntViewは恐らくIBOutletで本体のViewに接続されてたものと思われます。
http://www.awaresoft.jp/development/35-iphone-app/93-create-reusable-ui-with-interface-builder.html

ここでは、後者、すなわち、Nibファイルは一個のままでUIViewControllerを分割する方法を記録します。

−−−*.h−−−−

まず分割したいオブジェクトのヘッダファイルを記述します。

#import
@interface decimalMode : NSObject {
NSString *now;
UIButton *zeroButton, *add2Button , *twoButton, *FButton;

}
@property (nonatomic, retain) NSString *now;
@property (nonatomic, retain) IBOutlet UIButton *zeroButton, *add2Button , *twoButton, *FButton;
-(void) zero ;
-(void) add2 ;
-(void) two ;
-(void) flowting ;
@end

オブジェクト分割時の基本は、オブジェクトの操作をメソッド化(ここではzero- flowting)し、状態の読み取りをプロパティ化することにあります。
そして、操作するUIをアウトレットか化します(ここでは、zeroButton-FButton)。


−−−*.m−−−−


つぎに、実行ファイル(*.m)を記載しますが、ここでの注意点はNibが起動した際に、このオブジェクトを包含して起動してもらうことです。そのために以下のコードを付加します。


-(void) awakeFromNib {
    [super awakeFromNib];
}

あとは普通にzeroからflowtingまでの処理(ここではUIButtonの色操作)を実装します。


−−−*.xib−−−−

次にNibファイルにLibraryからオブジェクトを導入します。
この際、Command+F4でオブジェクトを追加したオブジェクトに変更します。
そうするとIBOutletで指定した足がCommand+F2とかで見ることができると思います。
この足を、マウス右クリック等で、該当するUI部品(この場合はボタン)と連接します。
ーーー*.UIViewController.hーーー

さらにUIViewContrller.hに、当該オブジェクトのヘッダファイルをインポートし、
さらに当該オブジェクトをアウトレット指定します。


#import "decimalMode.h"
@interface makidenViewController : UIViewController{
      ....


decimalMode *DecimalMode;
}

....
@property (nonatomic, retain) IBOutlet decimalMode *DecimalMode;

@end



さらに、InterfaceBuilderに戻り、File's OWnerから実装したオブジェクト(ここではDecimalMode)
に向けて、マウス右クリックしながらのドラックなどで、このアウトレットをオブジェクトとリンクします


ーーー*.UIViewController.m ーーー

お決まりの@synthesizeや=nil, [... release]を実装さえすれば、
オブジェクトが自動でロードされるため、初期化処理なしでいきなり当該オブジェクトを呼び出すことができます。

[DecimalMode zero];


以上です。やったね。

2011年6月22日水曜日

クラスを分割する。

プログラムの機能を増やして行くと、1つのオブジェクト内のコードが膨大となってしまい、メンテナンスがしずらくなります。この解決のためには、やはりオブジェクトとして意味のある単位で分割してまとめるが王道です。

小さく切出す場合は、UIViewの派生オブジェクトとして作るか、ビューコントローラの一部を切出してコントロールするかになるかと思います。しかしながら後者についてはAppleとして推奨しないようです。

実装する際は、これまでグローバル変数などで管理していた状態等を隠蔽しながら実装します。
そのため、状態遷移のためのメソッドを切出したオブジェクトに実装します。
また、呼び出しもとのオブジェクトの状態を確認するためには、プロパティとして状態変数を表に出します。

その結果、ヘッダファイルとしては以下のようなものとなります。


@interface decimalMode : UIView {
NSString *now;
}
// 状態をプロパティ化し、読み出し可能とする ex decimalMode.now
@property (nonatomic, retain) NSString *now;
// 状態を変化させる操作をインスタンス化する。インスタンスの名称には操作の意味を持たせる。
-(void) zero ;
-(void) add2 ;
-(void) two ;
-(void) flowting ;

-(IBAction) decimalPointButtonPressed:(id)sender;
@end

2011年6月16日木曜日

Xcode4でアプリを作る

・ソースコントロール
Window - organizer
左下のタブからAdd
リポジトリを外部のオープンソースから実装できる。<GitHub>


・ソースコードエディタ
 ナビゲーション、エディット、テスト
 右上の左から2番目のボタンでセカンドエディタを開くことができる(*.h、*.m)<Open Counter Part>
    *.mibファイルでは、左にインターフェース、右にソースコードを開くことができる。
 オプションキーを押してクリックすればセカンダリエディタに表示できる。
 ーを入れてCTRL+SPaceでメソッドの候補を出してくれる(Code snippets)。
 右下にある{ }はドラック&ドロップでソースの断片を格納、取り出しでき、繰り返しの入力をサポートしてくれる。
 入力中のバックグラウンドでエラー判定してくれる。黄色いバルーンをクリックしFIXボタンを押すと自動訂正する。

・検索と置換
   サーチナビゲータは、ある範囲での全てのコードを検索してくれる(左上の丸いアイコン)
 正規表現で検索することができる。
 置換はプレビューし、対象を選んでからリプレースすることができる。

・バージョンエディタ(右上、左から三番目)
 ログモード、ブレームモード(誰が)、コンパリジョンモード
 右下のジャンプバーで任意のバージョンに飛ぶことができる。
 真ん中の下のボタンで、タイムライン表示ができる。

2011年6月14日火曜日

Xcode 4の新概念

WWDC 2010のXcode4解説ビデオがiTunesUから既に無くなっている。
ダウンロードしておいてよかった。

ー ワークスペース ー
WorkSpaceというのがあるらしい。
プロジェクトも入ってない空の箱らしい。
Files- AddFilesでプロジェクトを読み込むことができる。ドキュメントも左のタブに読み込むことができる。また、スキームという概念のものも組み込むこおができる。Launch Schemes, Distribution Schemesといったものだ。
よくわからない。

プロジェクトはWorkSpace間でシェアすることができる。スキームマネージャで共有を選ぶらしい。

プロジェクトの中のファイルを編集するのはあまり変わらない。

ー ナビゲータ ー
ナビゲータとういうのが左の選択ボタンにある。クラス分類、サーチ、ブレークポイント、ログなどがある。
下にはフィルタリングのウィンドウがある。

ー エディター ー
スタンダード、アシスタント、バージョンエディタの3つがある。

ファイルとしては、ソース、インターフェースビルダ、データモデル、HEx, Previewがある。
ジャンプバー、アシスタントエディタ、インスペクター、ライブラリがある。

*.h と *.m を左右にならべ、ドラック&ドロップでインスタンスをコピーできる。

.nibファイルを選択すると、左にビルダー、右にソースなどで編集可能となる。
この際、ボタンとコードの間でドラックすると、アクションが実装できたりする。

範囲選択して、コードライブラリにドラックすると、そのコードが自動でカスタムコードとしてライブラリに格納される。ショートカットも登録できる。
すげー。

データモデルは、エンティ、アトリビュートを登録でき・・よくわからん。
まだ、つかったことないからな・・

ファイルは任意にHexエディットができる。

選択した型などは、左に説明がでてくれる。

ー オーガナイザー ー
Window - Organizerで起動する。
ドキュメントタブを選択すると、クラスリファレンスを見ることができる。
iPhoneタブでは、・・・
リポジトリタブでは、・・・
プロジェクトタブでは・・・
アーカイブタブでは・・・

ー バージョンエディタ ー
右の左から2?3?番目はバージョンエディタといい、だれがいつ変更したか記録を見ることができる。
異なるバージョンを左右で比較してみることができる。まんなかの黒いものが日付などのバージョンで選択して比較することができる。

ー デバッキング ー
あまり変わらない。
ブレークポイントでとまると、コンソールが自動で表示される。
エラーは真ん中の上にでて、クリックすると左のタブとコードに飛ぶことができる。

ー スキーム ー (新コンセプト)
ビルド/オブジェクトの生成を計画することができる。チーム作業に使うらしい。

ビルドフェーズ ー ターゲットの生成
テストフェーズ ー ユニットテスト、性能テスト・・
ラウンチフェーズ ー 

しかし、今つかっていない機能はやっぱりよくわからないなぁ・・

Xcode 4 を使い始めないと

そろそろXcode4を使い始めないとやばい
日本語でもいくつか参考書がではじめたらしいが、やはり高いなぁ・・

  

2011年6月11日土曜日

iOS5でのロック画面から直接カメラへ行く方法

iOS5は、ロック画面からカメラアプに直接移動できたり、ロック画面から音楽をコントロールできるはずですが、始めその方法が判りませんでした。

方法としては、簡単で
・ロック画面が表示されている状態で、ホームボタンを「ダブルクリックする」です。

気がつかなかったなぁ

2011年3月27日日曜日

Mac開発環境のアンインストール方法

sudo Developer/Library/uninstall-devtools --mode=all

2011年3月6日日曜日

メモリ不足への対処

組み込み型OSであるiOSの実装にあたり、メモリ管理を確実に行うことは可用性を保つ上で重要だ。”UIKit詳細リファレンス”に良い解説があった。メモリ不足対処には、didReceiveMemoryWarningが呼ばれることは周知だが、OS3.0からはviewDidUnloadが呼ばれるため、ここにコードすることになる。didRecieveMemoryWarningは、メモリ不足時に常に呼ばれるが、viewDidUnloadは前面にいるビューコントローラ以外のコントローラで呼ばれるようだ。そもそも画面遷移のときにはオブジェクトを解放してあげるのはマナーであるが、viewDidUnloadにもコードし、解放してあげることも必要となるようだ。

2011年2月26日土曜日

Chromeの翻訳はすごい

FacebookのブログリンクがSafariで動かないのでChromeで表示したところ?? なんか変だ・・最近英語でFacebookの回答書いていたので一瞬気づかなかったが、自分が日本語で書いたページが全部英語になっていた。Chromeおそるべし。

MS-Office for Macを試用期間を超えて使う方法

できちゃいました。簡単です。ずーっとアプリを立ち上げたままにしておけば試用期間を超えても使えちゃいます。電源を落とさないこと(爆)

Facebook対応iPhoneアプリの作り方(メモ)