1. ホーム
  2. iphone

iOSの場合 UIViewの 'drawRect:' とそのレイヤーのデリゲート 'drawLayer:inContext:' の使い分け。

2023-09-25 13:03:51

質問

のサブクラスであるクラスがあります。 UIView . を実装することによって、ビューの中に描画することができます。 drawRect メソッドを実装するか、あるいは drawLayer:inContext: のデリゲートメソッドである CALayer .

2つ質問があります。

  1. どのアプローチを使うか、どのように決定するのですか?それぞれにユースケースがあるのでしょうか?
  2. もし私が drawLayer:inContext: と呼ばれ、(かつ drawRect は呼び出されません。少なくともブレークポイントを置く限りでは)、たとえ私がビューを CALayer を使用して代表としてビューを割り当てなくても、ブレークポイントを置くことで分かるようになります。

    [[self layer] setDelegate:self];

    私のインスタンスがレイヤーのデリゲートとして定義されていない場合、どうしてデリゲートメソッドが呼び出されるのでしょうか? また、どのようなメカニズムによって drawRect が呼び出されるのを防ぐメカニズムは何ですか? drawLayer:inContext: が呼び出された場合に呼び出されないようにするには?

どのように解決するのですか?

<ブロッククオート

どのアプローチを使うか、どのように決定するのですか?それぞれにユースケースがあるのでしょうか?

常に使用する drawRect: を使用し、決して UIView を描画デリゲートとして使用しないでください。 CALayer .

私のインスタンスがレイヤーのデリゲートとして定義されていない場合、どうしてデリゲートメソッドが呼び出されるのでしょうか? また、以下の場合に drawRect が呼び出されるのを防ぐメカニズムは何でしょうか? drawLayer:inContext: が呼び出されるのを防ぐメカニズムは何ですか?

すべての UIView のインスタンスは、そのバックグランドである CALayer . そのため [[self layer] setDelegate:self]; は何もしていないように見えた。冗長なのです。その drawRect: メソッドは事実上ビューのレイヤーのための描画デリゲートメソッドです。内部的には UIView を実装しています。 drawLayer:inContext: を実装しており、独自の処理を行った後に drawRect: . デバッガで確認することができます。

このため drawRect: を実装したときに呼び出されなかったのは drawLayer:inContext: . また、このような理由から、決して CALayer 描画デリゲートメソッドをカスタム UIView のサブクラスを作成します。また、どのビューも他のレイヤーの描画デリゲートにするべきではありません。それはあらゆる種類の奇妙なことを引き起こすでしょう。

もし、あなたが drawLayer:inContext: にアクセスする必要があるため CGContextRef にアクセスする必要があるため、そのアクセスは drawRect: を呼び出すことで UIGraphicsGetCurrentContext() .