Подтвердить что ты не робот

Округлые углы только на вершине UIView

Привет, я ищу чистое решение без перезаписи drawRect или тому подобного, чтобы создать UIView с закругленными углами в верхней части Вид. Моя главная проблема здесь заключается в том, чтобы создать переменное решение, если представление будет изменено или что-то в этом роде. Есть ли чистое решение? Apple - это тоже в первом элементе таблицы. это не может быть так сложно сделать.

4b9b3361

Ответ 1

Вы можете сделать это, установив 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(), так что представление уже было изменено с раскадровки


В 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

Ответ 2

Просто попробовал с Swift 3.0, Xcode 8.0:

ПОМНИТЕ, чтобы установить кнопку в 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
    }
}
  • Вот результат:

Состояние по умолчанию:

введите описание изображения здесь

Сохраненное состояние:

введите описание изображения здесь

Надеюсь на эту помощь!

Ответ 3

Я справился с этим с помощью Эшли.

Прежде всего я подклассифицировал 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;
    } 
}

Ответ 4

Расширение для 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)

Ответ 5

Для iOS11 и более поздних версий вы можете использовать свойство слоя представления:

@property CACornerMask maskedCorners

Это определяет, какой из четырех углов получает маскировку при использовании свойства cornerRadius. По умолчанию все четыре угла. (Apple Doc)

Ответ 6

С быстрым 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

Важно: убедитесь, что это "layoutSubviews" не "awakeFromNib" (если вы используете TableViewCell) или аналогичные для UIView, или только верхний левый угол округлен!

Ответ 7

Современный & Простое решение

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

Ответ 8

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

    registerbtn.layer.mask = maskLayer;

это сделает только один округленный угол

Ответ 9

Простым способом сделать это будет определение пути в нужной форме и заполнение его любым цветом, который вы хотите использовать для фона. Вы можете использовать для этого UIBezierPath или CGPath. Например, используя CGPath, вы можете построить путь, используя такие методы, как CGMoveToPoint(), CGAddLineToPoint() и CGAddArc(). Затем вы заполните его CGContextFillPath(). Посмотрите Quartz 2D Programming Guide для полного обсуждения.

Другим способом было бы добавить subview с закругленными углами (вы можете установить свойство subview layer cornerRadius), но пусть одна сторона подвью будет обрезана родительским представлением.

Третий способ - добавить фоновое изображение с желаемой формой. Вы можете сделать углы прозрачными и сделать вид фона прозрачным, и вы получите желаемый эффект. Однако это не будет работать для изменения размера.

Где вы застреваете?