web-dev-qa-db-ja.com

UIViewの上部のみの角丸

こんにちは、drawRectまたはそのようなものを上書きせずに、きれいなソリューションを検索して、Viewの上部に角の丸いUIViewを作成しています。ここでの私の主な問題は、ビューのサイズが変更されている場合など、可変ソリューションを作成することです。クリーンなソリューションはありますか? Appleこれは、最初のテーブル項目でも同様です。これを行うのはそれほど難しくありません。

45
mariusLAN

これを行うには、ビューのレイヤーに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()メソッドでこれを行う必要があるため、ビューはストーリーボードから既にサイズ変更されています


In Swift <= 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
_

Swift 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
_
158
Ashley Mills

_Swift 3.0_、_Xcode 8.0_で試しました:

[〜#〜] remember [〜#〜]viewDidLayoutSubviews()またはlayoutSubViewsのボタンを@に設定するrobの説明 ここ

そして、ボタンの背景を変更したい場合は、以下を呼び出すだけです。

_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
    }
}
_
  • 結果は次のとおりです。

デフォルト状態:

enter image description here

隔離された状態:

enter image description here

この助けを願っています!!

14
Nhat Dinh

選択したコーナーを丸める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)
4

私はアシュリーの助けを借りてこれを解決しました。

まず、iViewをサブクラス化しました。 - (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;
    } 
}
4
mariusLAN

IOS11以降では、ビューのレイヤープロパティを使用できます。

@property CACornerMask maskedCorners

cornerRadiusプロパティを使用する場合、4つのコーナーのどれがマスキングを受け取るかを定義します。デフォルトは4つのコーナーすべてです。 (Appleドキュメント)

3
Fede Henze

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'にあること、または左上隅のみが丸くなっていることを確認してください!

2
nlapham21

モダンで簡単なソリューション

iOS 11 +

これで、ビューのレイヤーに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

これは次のようなものです。

enter image description here

1
Trev14
 CAShapeLayer * maskLayer = [CAShapeLayer layer];
    maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: registerbtn.bounds byRoundingCorners: UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii: (CGSize){9.0, 12.0}].CGPath;

    registerbtn.layer.mask = maskLayer;

これは角を丸くするだけです

0
user7305997