はじめに
Cocoa Touchには、Mac OS Xのインターフェイスを操作するためのクラスとメソッドを提供するAppKitが含まれていないことが知られています。iOSプラットフォームのAppKitの代わりに、2Dは低レベルCore Graphics Cフレームワークを使用しますC関数とメモリの操作は、AppKitのObjective-Cクラスほど便利で柔軟性がないためです。 さらに、Core Graphicsを使用する場合、より多くのコードを記述する必要があることは明らかです。これは、拡張および保守がより困難です。 この記事では、カスタムビューを作成し、フレームワークの機能を理解します。
はじめに
まず、アプリケーションを作成し、カスタムビューを追加する必要があります。その上にオブジェクトをさらに描画します。
Xcodeビューベースのアプリケーションを作成し、グラフィックスと呼びます。
次に、ビュー(Cmd + N)を追加し、MyCanvasと呼びます。
これは、Objective-CクラスとUIViewのサブクラスになります。
すべての「描画」はメソッド内で発生します。
- (void)drawRect:(CGRect)rect
{
//
}
-drawRect:メソッドを直接呼び出すことはありません。 ビューが初期化されるときに実行されるこのメソッドのみを実装します。
コンテンツを更新するには、このビューまたはその一部(aRect)を更新する必要がある場合、UIViewメソッドを使用します
-(void)setNeedsDisplay;
-(void)setNeedsDisplayInRect:(CGRect)aRect;
それに応じて。
drawRect:メソッドを使用して、単純な正方形を描画します。 すべての描画はコンテキスト内で行われ、コンテキストは描画の行われる場所を決定します。 コンテキストを取得するには、UIGraphicsGetCurrentContext C関数を使用します。 iOSでは、Mac OS Xのように、描画時の参照の中心は左下ではなく左上にあります。
- (void)drawRect:(CGRect)rect
{
// context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect); // context
CGContextSetRGBFillColor(context, 255, 0, 0, 1);
CGContextFillRect(context, CGRectMake(20, 20, 100, 100));
}
この場合、グラフィックを再描画しないため、コンテキストをクリアする必要はありませんが、描画する前にグラフィック要素をクリアすることをお勧めします。 クリーニング後にビューが黒くなることに注意してください。
CGContextSetRGBFillColor関数はこのコンテキストの塗りつぶし色を設定し、CGContextFillRect関数は正方形を描画します。
次に、シミュレーターでアプリケーションを実行し(Cmd + R)、見てのとおり、何も起こりませんでした。 実際には、ビューを作成せず、階層に追加しませんでした。
ビューを作成するには、カスタムビュー-Interface Builderおよび直接コードを使用するなど、2つの方法があります。 IBに関しては、すべてが簡単です。ドラッグアンドドロップでUIView要素を追加し、IDインスペクターでカスタムクラス:MyViewに設定します。
ビューを手動で作成するには、GraphicsViewController.mで作成します。
- (void)viewDidLoad
{
[super viewDidLoad];
MyCanvas *myView = [[MyCanvas alloc] initWithFrame:self.view.bounds];
[self.view addSubview:myView];
}
AddSubview:は、Viewを階層に追加するために使用され、removeFromSuperview:を階層から削除します。 この場合、最初のメソッドはスーパービューに送信され、2番目のメソッドは削除する必要があります。
メモリの操作の詳細については、記事の最後で説明します。ここでは、階層のトップビューからリリースする際に留意する必要があることに注意してください。また、サブビューもすべてリリースします。後でそれらを参照すると、アプリケーションがクラッシュします。
これで、アプリケーションを起動すると、20ポイントのインデントが付いた赤い正方形が表示されます。
描画時には、ピクセル(px)ではなくポイント(pt)を使用するため、Retinaと通常のディスプレイでサイズが同じになります。 ピクセルの使用も可能です。 特定のデバイスの画面の種類を決定するには、@ property CGFloat contentScaleFactorプロパティを使用します。 「スケール」(画面上の特定のビューのポイントのピクセル数)を返します。 値は、網膜の場合は2.0、通常の画面の場合は1.0です。
他のプリミティブを使用することを検討してください。
1)CGContextFillEllipseInRectメソッドによって青い塗りつぶしのある円が作成され、長方形に収まるため、楕円を作成できます。
CGContextSetRGBFillColor(context, 0, 0, 255, 1);
CGContextFillEllipseInRect(context, CGRectMake(30, 140, 80, 80));
2)緑の輪郭と線の太さが3の塗りのない円、線の太さはCGContextSetLineWidthメソッドを使用して設定され、塗りのない円はCGContextStrokeEllipseInRectメソッドを使用して描画されます。
CGContextSetRGBStrokeColor(context, 0, 255, 0, 1);
CGContextSetLineWidth(context, 3.0);
CGRect circleRect = CGRectMake(140, 20, 100, 100);
CGContextStrokeEllipseInRect(context, circleRect);
3)赤い正方形に内接する三角形が、配列の点に描かれます。
CGContextSetRGBStrokeColor(context, 255, 0, 255, 1);
CGPoint points[6] = {CGPointMake(70, 20), CGPointMake(120, 120),
CGPointMake(120, 120), CGPointMake(20, 120),
CGPointMake(20, 120), CGPointMake(70, 20)};
CGContextStrokeLineSegments(context, points, 6);
4)ベジェスプライン。 この場合、開始点と終了点、および曲率を指定する点の座標を指定する必要があります。 ベジェ曲線に精通していない人のために、簡単なクラッシュコース:
混乱しないように、ポイントを個別のCGPointとして設定します。
CGPoint bezierStart = {20, 260};
CGPoint bezierEnd = {300, 260};
CGPoint bezierHelper1 = {80, 320};
CGPoint bezierHelper2 = {240, 320};
CGContextBeginPath(context);
CGContextMoveToPoint(context, bezierStart.x, bezierStart.y);
CGContextAddCurveToPoint(context,
bezierHelper1.x, bezierHelper1.y,
bezierHelper2.x, bezierHelper2.y,
bezierEnd.x, bezierEnd.y);
CGContextStrokePath(context);
より複雑な要素、たとえば正弦波を描いてみましょう。
CGContextSetRGBStrokeColor(context, 255, 255, 255, 1);
int y;
for(int x=rect.origin.x; x < rect.size.width; x++)
{
y = ((rect.size.height/6) * sin(((x*4) % 360) * M_PI/180)) + 380;
if (x == 0) CGContextMoveToPoint(context, x, y);
else CGContextAddLineToPoint(context, x, y);
}
CGContextStrokePath(context);
5行目では、関数を垂直方向に下に移動するために380ポイントを追加しました。
その結果、アプリケーションを起動した後のiPhoneの画面は次のようになります。
テキストを操作する
テキストを表示する最も便利な方法は、テキストを変換するための多くのメソッドを備えたUILabelオブジェクトを使用することです。 ただし、たとえば、テキストを回転させたい場合など、-drawRectメソッドでテキストを描画する必要がある場合があります。
コアグラフィックスを使用した描画:
char *txt = "My CG text"; // ,
CGContextSelectFont(context, "Helvetica", 18.0, kCGEncodingMacRoman); //
CGContextSetTextDrawingMode(context, kCGTextFill); // : kCGTextFill () kCGTextStroke ()
CGContextShowTextAtPoint(context, 20, 280, txt, strlen(txt)); //
UIFontオブジェクトを使用して、フォント、サイズ、表示スタイル、メトリックを選択できます。 [UIFont familyNames]メソッドを使用すると、使用可能なフォントの配列を取得できます。
UILabelを使用し、同時にInterface Builderではなくプログラムで作成する場合は、GraphicsViewController.mに次のコードを追加します。
UILabel *scaleNumber = [[UILabel alloc] initWithFrame:CGRectMake(160, 140, 140, 21)]; // , View
scaleNumber.textColor = [UIColor yellowColor]; //
scaleNumber.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; // , ( )
scaleNumber.text = @"Vitaly Ishkulov"; //-
scaleNumber.adjustsFontSizeToFitWidth = YES; // , , , ( , )
[myView addSubview:scaleNumber]; // View
[scaleNumber release]; // , / myView
結論とメモリの操作に関するいくつかの言葉
ビューをメモリから解放するには、[myView release]を使用しないでください。 代わりに、releaseOutletsメソッドを作成します。
- (void)releaseOutlets {
self.myView = nil;
}
そして、viewDidUnloadおよびdeallocからこのメソッドを呼び出します。
- (void)viewDidUnload
{
[super viewDidUnload];
[self releaseOutlets];
// Release any retained subviews of the main view.
// eg self.myOutlet = nil;
}
- (void)dealloc
{
[self releaseOutlets];
[super dealloc];
}
少し奇妙な式self.myView = nil; 実際には、セッターを見ると簡単に説明できます。セッターは、私のmysynthコマンドを合成します。
- (void)setMyView:(MyCanvas *)anObject
{
if (anObject != myView) {
[myView release];
myView = [anObject retain];
}
}
anObject = nilの場合、メソッドはメソッドの最後の行をmyView nilに設定し、前の行は現在のビューをメモリから解放します。
これでCoreGraphicsの簡単な紹介は終わりです。誰かに役立つと思います。
さらなる研究のためのリンク:
iOS向けプログラミングガイドを見る
コアグラフィックスフレームワークリファレンス