2017-03-15 5 views
1

私の目標は、カスタムのUIButtonサブクラスを作成し、いくつかの追加機能を備えた丸い(または丸い四角形の)ボタンを作成することです。 、限りカスタムdrawRectでラウンドUIButtonを作成する:

@implementation MyRoundButton

-(id)initWithFrame:(CGRect)frame{ 
    if (self = [super initWithFrame:frame]) 
     [self setupView]; 

    return self; 
} 

-(id)initWithCoder:(NSCoder *)aDecoder{ 
    if(self = [super initWithCoder:aDecoder]) 
     [self setupView]; 

    return self; 
} 

-(void)setupView {  
    self.layer.cornerRadius = MIN(self.frame.size.height, self.frame.size.width)/2.0; 
} 

これはに正常に動作します:

は、いくつかの検索の後、私は単純にボタン層のcornerRadiusを設定すると丸いボタンを作成する最も簡単な方法であることがわかりました私はもちろんdrawRect:

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

をオーバーライドしないように私はにいくつかのカスタム描画コードを追加したいと思いますしかし、[super drawRect:rect]ボタンだけがもう丸められていなくても、その範囲内で矩形で描かれます。

これはどのように可能ですか?シンプルなスーパーコールでメソッドをオーバーライドすると、ビヘイビアがまったく変わることはありますか?

どうすればこの問題を回避できますか?私はすでにレイヤーを変更せずに、単に手動で背景を描画するようにしました。drawRect:です。しかし、ボタンはバックグラウンドの矩形を描画し、カスタム図面はその上に表示されます。

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

+0

を参照してください。 drawRectを使用してそれ自体を実装する必要はありません。 –

+0

これは説明かもしれませんが、そのような実装の理由は何でしょうか?何も変わらないコードは何か変わる?非常に奇妙な...しかし、実際の問題は何か他のものです: 'drawRect:'を使う丸いボタンを作る方法 –

+0

なぜ[[super drawRect:rect]; '? – DonMag

答えて

1

例のレイヤーには、角の半径を持つ背景が含まれていますが、空のオーバーライドdrawRect:は無視されます。これは、通常、UIViewのインスタンスは、コンテンツをレンダリングするための組み込みレイヤ(CALayerのインスタンス)に依存するため、drawRect:は呼び出されません。ただし、レイヤーは描画ビヘイビアーをビューに委譲できますが、drawRect:を実装するとレイヤーが描画ビヘイビアを委譲できます。

UIViewを単純にサブクラス化する場合は、これは問題ありません。しかし、UIButtonのようなフレームワークコンポーネントをサブクラス化するのは少し面白いです。 1つの潜在的な問題は、-[super drawRect:]への呼び出しです。それが原因と思われるいたずらを正確に知るのは難しいですが、それが問題の原因かもしれません。既定では、UIButtonはカスタム描画を行う必要はありません。プライベートクラスのネストされたインスタンスUIButtonLabelが含まれています。このインスタンスはボタンのタイトルを描画します。

内部の詳細がプライベートであるクラスの描画動作をオーバーライドするのではなく、1つ以上の静的イメージを使用し、1つ以上の状態のボタンの背景イメージプロパティを設定することを検討してください。これは何かを変更した場合

+0

ありがとう、その音はかなり妥当です。しかし、私はこれが完全に真実であるとは確信していません。レイヤー描画からビュー描画に切り替えるトリガーとして 'drawRect:'を実装するのが分かり、単純に無視されるでしょう。しかし、そうではありません。 'drawRect:'が実装されている場合、そのレイヤーは常にバックグラウンドになり、そうしないようにはできません。つまり、レイヤー描画はまだ有効です。ビュー描画のみを追加できますが、私の目標は**レイヤー描画を置き換えることです。これどうやってするの? –

+0

私は自分の答えを編集しました。 ' - [super drawRect:]'の呼び出しを取り除こうとしましたか? – jlehr

+0

'super'呼び出しは、何も変更しない' drawRect: 'のオーバーライドバージョンでさえ、問題につながることを実証するためだけに使われました。 'supper'呼び出しを削除しても何も変わりません。 オーバーライドバージョンを追加しても、何かを変更するだけで十分です。しかし、Itheの主な目標は同じです:どのようにUIButtonをオーバーライドすると、ラウンドを作成し、同時にカスタム図面を使用しますか?カスタム描画は、ボタンがその背景レイヤーを傷つけるのを防ぐことができないので、機能しません。これ以上レイヤーを設定することはできません。 –

0

はUIButtonは、オーバーライドをチェックし、異なる動作をすることができ、「どのように動作を変更する簡単なスーパーコールでメソッドをオーバーライドすることができます」...

-(void)setupView {  
    self.layer.cornerRadius = MIN(self.frame.size.height, self.frame.size.width)/2.0; 
    self.clipsToBounds = YES; 
} 
+0

これは部分的に問題を解決します:カスタム描画(override)を使用していても、ボタンは丸みを帯びていますが、ボタンはクリップされました。 (驚き、驚き:)とレイヤーに追加された**シャドウ**はもう見ることができません... –

+0

申し訳ありませんが、あなたの質問に影を必要とすることについて何も見たことがありませんでした。物事を行うには複数の方法があります...もしあなたが最終目標を掲示しているのであれば? – DonMag

関連する問題