こんにちは私は、ビューの上部に丸みを帯びた角を持つdrawRect
を作成するために、上書きなどのないクリーンなソリューションを探しています。ここでの私の主な問題は、ビューのサイズが変更されている場合などに変数ソリューションを作成することです。クリーンな解決策はありますか?Appleはこれも最初のテーブルアイテムで行っています。これを行うのはそれほど難しいことではありません。UIView
10 に答える
これを行うには、ビューのレイヤーにを設定mask
します。
CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: self.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath;
self.layer.mask = maskLayer;
重要:ビューのlayoutSubviews()
メソッドでこれを行う必要があるため、ビューはストーリーボードから既にサイズ変更されています
スイフト<=1.2
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: .TopLeft | .TopRight, cornerRadii: CGSize(width: 10.0, height: 10.0)).CGPath
layer.mask = maskLayer
スイフト2.x
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: UIRectCorner.TopLeft.union(.TopRight), cornerRadii: CGSizeMake(10, 10)).CGPath
layer.mask = maskLayer
Swift 3.x
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath
layer.mask = maskLayer
で試してみましSwift 3.0
たXcode 8.0
:
ここで説明されている@robに、または@robとしてボタンviewDidLayoutSubviews()
を設定することを忘れないでください。layoutSubViews
また、ボタンの背景を変更したい場合は、次の電話番号に電話するだけです。
yourButton.backgroundColor = UIColor.someColour
ソース:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
yourButton.layer.masksToBounds = true
yourButton.roundCorners(corners: [.topLeft,.topRight], radius: 5)
}
extension UIButton
{
func roundCorners(corners:UIRectCorner, radius: CGFloat)
{
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)).cgPath
self.layer.mask = maskLayer
}
}
- 結果は次のとおりです。
デフォルトの状態:
選択状態:
この助けを願っています!
モダンで簡単なソリューション
iOS11以降
これmaskedCorners
で、ビューのレイヤーにプロパティが作成され、作業がはるかに簡単になりました。
目的のコーナー半径を設定し、マスクするコーナーを指定するだけです。最良の部分は、これが境界線でうまく機能することです-レイヤーの境界線は、丸みを帯びているかどうかに関係なく、レイヤーのエッジに従います!遊び場で次のコードを試してください(ライブビューを押して開いて、command+option+return
どのように見えるかを確認してください)
import UIKit
import PlaygroundSupport
let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 160))
wrapperView.backgroundColor = .lightGray
let roundedCornerView = UIView(frame: CGRect(x: 50, y: 50, width: 300, height: 60))
roundedCornerView.backgroundColor = .white
wrapperView.addSubview(roundedCornerView)
roundedCornerView.layer.cornerRadius = 10
roundedCornerView.layer.borderColor = UIColor.red.cgColor
roundedCornerView.layer.borderWidth = 1
// this is the key part - try out different corner combinations to achieve what you need
roundedCornerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
PlaygroundPage.current.liveView = wrapperView
外観は次のとおりです。
iOS11以降では、ビューのレイヤープロパティを使用できます。
@property CACornerMask maskedCorners
これは、cornerRadiusプロパティを使用するときに、4つのコーナーのどれがマスキングを受け取るかを定義します。デフォルトは四隅すべてです。(Apple doc)
選択したコーナーを丸めるUIViewの拡張機能(Swift 4):
extension UIView {
/// Round UIView selected corners
///
/// - Parameters:
/// - corners: selected corners to round
/// - radius: round amount
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
例:
ratingView.roundCorners([.topLeft, .topRight, .bottomRight], radius: 6)
私はアシュリーの助けを借りてこれを解決しました。
まず、UIViewをサブクラス化しました。と呼ばれるクラスの独自のコンストラクターを作成し- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath;
ます。このコンストラクターでは、スタイルを設定するテーブルセルの種類を決定します。
次に、lを上書きして、レイヤーマスク- (void)layoutSubviews
を作成して適用します。CAShapeLayer
.hファイルコード
typedef enum {
tableCellMiddle,
tableCellTop,
tableCellBottom,
tableCellSingle
} tableCellPositionValue;
@interface TableCellBackgrounds : UIView
{
tableCellPositionValue position;
}
- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath;
@end
.mファイルコード
- (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath
{
self = [super initWithFrame:aView.frame];
[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
if(self)
{
[self setBackgroundColor:[UIColor colorWithRed:(float)230/255 green:(float)80/255 blue:(float)70/255 alpha:1]];
if(table.style == UITableViewStyleGrouped)
{
int rows = [table numberOfRowsInSection:indexPath.section];
if(indexPath.row == 0 && rows == 1)
{
self.layer.cornerRadius = 11;
position = tableCellSingle;
}
else if (indexPath.row == 0)
position = tableCellTop;
else if (indexPath.row != rows - 1)
position = tableCellMiddle;
else
position = tableCellBottom;
}
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
if(position == tableCellTop)
{
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:(CGSize){10.0, 10.0}].CGPath;
self.layer.mask = maskLayer;
}
else if (position == tableCellBottom)
{
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:(CGSize){10.0, 10.0}].CGPath;
self.layer.mask = maskLayer;
}
}
swift 3.0では、以下がうまくいきました
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath
(imageView.)layer.mask = maskLayer
重要:これが「awakeFromNib」(TableViewCellを使用している場合)またはUIViewの同様のものではなく、「layoutSubviews」にあることを確認してください。そうでない場合は、左上隅のみが丸められます。
Objective-Cでは次のようになります。
[oCollectionViewCell.layer setMasksToBounds:YES];
[oCollectionViewCell.layer setCornerRadius:5.0];
[oCollectionViewCell.layer setMaskedCorners:kCALayerMinXMinYCorner|kCALayerMaxXMinYCorner];
CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: registerbtn.bounds byRoundingCorners: UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii: (CGSize){9.0, 12.0}].CGPath;
registerbtn.layer.mask = maskLayer;
これは、丸みを帯びた1つのコーナーのみを実行します
これを行う簡単な方法は、必要な形状でパスを定義し、背景に使用する色でパスを塗りつぶすことです。UIBezierPath
またはこれに使用できますCGPath
。CGPath
たとえば、を使用すると、、、、などのメソッドを使用してパスを作成できCGMoveToPoint()
ます。次に、それをで埋めます。完全な議論については、Quartz2Dプログラミングガイドをご覧ください。CGAddLineToPoint()
CGAddArc()
CGContextFillPath()
もう1つの方法は、角が丸いサブビューを追加することです(サブビューのレイヤーのcornerRadiusプロパティを設定できます)が、サブビューの片側を親ビューでクリップします。
3番目の方法は、目的の形状の背景画像を追加することです。コーナーを透明にし、ビューの背景を透明にすることができ、目的の効果が得られます。ただし、これはサイズ変更にはあまり適していません。
どこで行き詰まっていますか?