7

drawRect:カスタム ビューで UIViewのメソッドをオーバーライドしようとしています。ただし、私のビューには次のように定義された境界半径があります。

    sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0];
    [self addSubview:sub];
    [sub setUserInteractionEnabled:YES];
    [self setUserInteractionEnabled:YES];
    CALayer *layer = sub.layer;
    layer.masksToBounds = YES;
    layer.borderWidth = 5.0;
    layer.borderColor = [UIColor whiteColor].CGColor;
    layer.cornerRadius = 30.0;

これは完全に機能し、ビューの周囲に境界線の半径を持つ素敵な境界線を配置します (背面の対角線/直線の白い線は気にしないでください。このビューとは関係ありません):

正しいもの

drawRect:ただし、ビューでメソッドをオーバーライドしようとすると、黒い背景が境界をマスキングしていないことがわかります。私は(現在)何もしません。ここに私のコードがあります:

-(void)drawRect:(CGRect)rect{
    [super drawRect:rect];
}

結果は次のとおりです。

間違ったもの

描画方法以外は何も変更していません。ビューをコーナー半径マスクに従わせながら、描画メソッドをオーバーライドするにはどうすればよいですか? これは iOS のバグですか、それとも何か不足していますか?

4

4 に答える 4

3

完全な答えはわかりませんが、実装drawLayer:inContext:しているかどうかによって UIView の実装が異なることは知ってdrawRect:います。おそらく、境界へのマスキング/クリッピングは、異なる方法で行うことの 1 つです。

問題を解決するには、いくつかの方法があります。

  • 背景を透明にします:

        layer.backgroundColor = [UIColor clearColor].CGColor;
    
  • custom 内にクリップしますdrawRect::

    - (void)drawRect:(CGRect)rect {
        [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:30.0] addClip];
        [image drawInRect:rect];  // or whatever
    }
    
  • 角を明示的に切り取る:

    CGContextBeginPath(c);
    CGContextAddArc(c, r, r, r, M_PI, 3*M_PI_2, 0);
    CGContextAddLineToPoint(c, 0, 0);
    CGContextClosePath(c);
    CGContextClip(c);
    [[UIColor grayColor] setFill];
    UIRectFill(rect);
    

WWDC 2010 の素晴らしいプレゼンテーションから最後の 2 つの提案を盗みました: iPhone OS での高度なパフォーマンスの最適化(ビデオはこのインデックス ページにリストされていますが、直リンクはありません)。

于 2013-04-24T00:56:45.883 に答える
2

これは古い質問ですが、最近Abusing UIViewというタイトルの役立つブログ記事を読んでいました。drawRectその中で、著者は、他の方法がある場合に境界線を追加するなどのことをオーバーライドしないようにアドバイスしています。彼は言い​​ます、

オーバーライドdrawRect:すると、パフォーマンス ヒットが発生します。私はそれをプロファイリングしていないので、通常の状況でそれが重要なパフォーマンスであるかどうかはわかりません (おそらくそうではないでしょう) が、ほとんどの場合、オーバーライドする人々drawRect:は、ビューのレイヤー プロパティにプロパティを設定することで、必要なことをはるかに簡単に達成できます。 . ビューの周りにアウトラインを描く必要がある場合は、次のようにします。

#import <QuartzCore/QuartzCore.h>

- (id)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
      self.layer.borderWidth = 2.f;
      self.layer.borderColor = [UIColor redColor].CGColor;
  }
  return self;

これはおそらく黒い背景が透けて見える問題を解決しないと思います。それは考えるべき別のことです。

于 2015-06-18T14:51:37.137 に答える