Давать UIView закругленные углы

577

В моем представлении входа в систему есть подпредставление UIActivityViewс UILabelнадписью «Вход в систему…». У этого подпредставления есть углы, которые не округлены. Как я могу сделать их круглыми?

Есть ли способ сделать это внутри моего XIB?

itsaboutcode
источник
6
Чтобы сделать что-то подобное в IB, потребуется предварительно обработанное изображение с закругленными углами
Эд Марти,
9
Не обязательно @ ed-marty. Этот ответ от @Gujamin заслуживает еще большего уважения, поскольку показывает, как применить cornerRadiusсвойство к таблице только с помощью Interface Builder, без необходимости использовать предварительно отрендеренные изображения или устанавливать его в коде.
djskinner

Ответы:

1219

Попробуй это

#import <QuartzCore/QuartzCore.h> // not necessary for 10 years now  :)

...

view.layer.cornerRadius = 5;
view.layer.masksToBounds = true;

Примечание. Если вы пытаетесь применить закругленные углы к представлению a UIViewController, его следует применять не в конструкторе контроллера представления, а в -viewDidLoad, после того, как viewон фактически создан.

Эд Марти
источник
6
Обратите внимание, что свойство существует только в iPhone 3.0, а не в более ранних версиях.
Кендалл Хельмштеттер Гелнер
5
Я просто должен сказать, что это был один из самых приятных ответов, которые я когда-либо видел на SO. Проверка здесь сначала сэкономила мне час борьбы с графическим редактором и сделала бы мой взгляд более хрупким к изменениям цвета / размеров. Спасибо!
Джастин Сирлз
20
Примечание по теме: всем, кто интересуется большим количеством визуальных полезностей (например, теней) для легкого применения к UIView, следует проверить ссылку на класс CALayer. Большинство из них так же просто, как установить одно или два значения свойства, как в ответе выше: developer.apple.com/mac/library/documentation/GraphicsImaging/…
Джастин Сирлс
6
@ Бен Коллинз (или кто-либо другой, у кого есть эта проблема), убедитесь, что в вашем представлении установлены «клипы подпредставлений». Вы можете проверить это в конструкторе интерфейсов.
Зем
2
это прекрасно работает, НО, если у вас есть много этих закругленных углов в любом виде прокрутки или анимации (я пытался использовать их в UITableView), ваша производительность сильно пострадает. Хороший гладкий вид таблицы прокрутки быстро стал прерывистым :(
Slee
261

Вы также можете использовать опцию User Defined Runtime Attributes конструктора интерфейса, чтобы установить путь layer.cornerRadiusк значению ключа . Убедитесь, что вы включили QuartzCoreбиблиотеку.

Этот прием также работает для установки layer.borderWidth, однако он не будет работать, так layer.borderColorкак ожидается, что a CGColorне будет UIColor.

Вы не сможете увидеть эффекты в раскадровке, поскольку эти параметры оцениваются во время выполнения.

Использование Interface Builder для установки радиуса угла

Gujamin
источник
10
Не забудьте проверить Clip Subviewsопцию для просмотра IB, а также
Питер
2
(или) добавить путь к ключу: layer.masksToBounds, тип: boolean: проверено
Amitabh
64

Теперь вы можете использовать быструю категорию в UIView (код под картинкой) в @IBInspectable, чтобы показать результат на раскадровке (Если вы используете категорию, используйте только cornerRadius, а не layer.cornerRadius в качестве ключевого пути.

extension UIView {
    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }
}

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

Гильерме Торрес Кастро
источник
И если вы используете собственный подкласс, не забудьте пометить его, @IBDesignableчтобы получить предварительный просмотр в IB! (Больше на nshipster.com/ibinspectable-ibdesignable )
Clozach
56

стриж

Короткий ответ:

myView.layer.cornerRadius = 8
myView.layer.masksToBounds = true  // optional

Дополнительный ответ

Если вы пришли к этому ответу, вы, вероятно, уже видели достаточно, чтобы решить вашу проблему. Я добавляю этот ответ, чтобы дать немного более наглядное объяснение того, почему вещи делают то, что делают.

Если вы начнете с обычного, у UIViewнего есть квадратные углы.

let blueView = UIView()
blueView.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
blueView.backgroundColor = UIColor.blueColor()
view.addSubview(blueView)

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

Вы можете дать ему закругленные углы, изменив cornerRadiusсвойство представления layer.

blueView.layer.cornerRadius = 8

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

Большие значения радиуса дают более закругленные углы

blueView.layer.cornerRadius = 25

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

и меньшие значения дают меньше закругленных углов.

blueView.layer.cornerRadius = 3

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

Этого может быть достаточно, чтобы решить вашу проблему прямо здесь. Однако иногда представление может иметь подпредставление или подуровень, выходящий за границы представления. Например, если бы я , чтобы добавить к югу вид , как это

let mySubView = UIView()
mySubView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
mySubView.backgroundColor = UIColor.redColor()
blueView.addSubview(mySubView)

или если бы я должен был добавить подслой, как это

let mySubLayer = CALayer()
mySubLayer.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
mySubLayer.backgroundColor = UIColor.redColor().CGColor
blueView.layer.addSublayer(mySubLayer)

Тогда я бы в конечном итоге

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

Теперь, если я не хочу, чтобы вещи висели за пределами границ, я могу сделать это

blueView.clipsToBounds = true

или это

blueView.layer.masksToBounds = true

который дает этот результат:

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

Оба clipsToBoundsи masksToBoundsявляются эквивалентными . Просто первый используется с, UIViewа второй - с CALayer.

Смотрите также

Suragch
источник
4
Я также хотел бы добавить, что установка радиуса угла на половину более короткой стороны (в данном случае blueView.frame.size.height/2) приводит к идеально закругленному углу.
Иоганн Берджесс
44

Другой подход, чем тот, который сделал Эд Марти:

#import <QuartzCore/QuartzCore.h>

[v.layer setCornerRadius:25.0f];
[v.layer setMasksToBounds:YES];

Вам нужен setMasksToBounds для загрузки всех объектов из IB ... У меня возникла проблема, когда мой взгляд округлился, но не было объектов из IB: /

это исправило это = D надеюсь, это поможет!

Кристиан Флэтхайм Йенсен
источник
48
как это отличается? кроме не используя точечный синтаксис?
user102008
3
[v.layer setMasksToBounds: YES]; \ n эта линия волшебная, она решает мою большую проблему
Cullen SUN
3
Я написал это, когда начал разработку для iOS, и не знал, что нет разницы между синтаксисом точек и синтаксисом скобок. Поэтому я написал это как "другое". Мой код также включал импорт <>, которого Эд Марти не имел в своем первоначальном ответе (позже отредактирован в), и поэтому мой ответ помогает людям решить их проблему (иначе говоря, не импортировать его).
Кристиан Флэтхайм Йенсен
28

Как описано в этом сообщении в блоге , вот метод, чтобы закруглить углы UIView:

+(void)roundView:(UIView *)view onCorner:(UIRectCorner)rectCorner radius:(float)radius
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds
                                                   byRoundingCorners:rectCorner
                                                         cornerRadii:CGSizeMake(radius, radius)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view.bounds;
    maskLayer.path = maskPath.CGPath;
    [view.layer setMask:maskLayer];
    [maskLayer release];
}

Самое интересное в этом то, что вы можете выбрать, какие углы вы хотите округлить.

pabloruiz55
источник
6
Вместо того, чтобы просто указывать ссылку на внешний сайт, мы предпочитаем, чтобы ответы здесь содержались самостоятельно, поэтому я привел соответствующий код из ссылки в блоге в ваш ответ. Люди могут посетить пост в блоге для получения более подробной информации, но это гарантирует, что контент выживет, если пост исчезнет. Кроме того, вы разместили этот ответ на несколько разных вопросов, которые на самом деле не задавали одно и то же. Те были удалены, и один вопрос был закрыт как дубликат этого. Нам нравится получать ответы, соответствующие каждому вопросу.
Брэд Ларсон
5
Предвидения. В блоге сейчас 404 сообщения.
Энтони C
Этот подход чистый, но он скрывает любой эффект тени на виде.
thesummersign
19

Вам необходимо сначала импортировать заголовочный файл <QuartzCore/QuartzCore.h>

 #import QuartzCore/QuartzCore.h>

[yourView.layer setCornerRadius:8.0f];
yourView.layer.borderColor = [UIColor redColor].CGColor;
yourView.layer.borderWidth = 2.0f;
[yourView.layer setMasksToBounds:YES];

Не пропустите - setMasksToBoundsиначе эффект может не проявиться.

Самир Джварчан
источник
2
Не нужно импортировать «QuartzCore / QuartzCore.h»
Судхир Кумар
Да, вам нужно импортировать.
Лорд Жолт
3
@LordZsolt Может быть, они изменили это с iOS7, но вам больше не нужно импортировать QuartzCore.
Марк
15

Вы можете использовать следующий пользовательский UIViewкласс, который также может изменить цвет и ширину границы. Так как IBDesignalbeвы можете изменить атрибуты в конструкторе интерфейсов.

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

import UIKit

@IBDesignable public class RoundedView: UIView {

    @IBInspectable var borderColor: UIColor = UIColor.white {
        didSet {
            layer.borderColor = borderColor.cgColor
        }
    }

    @IBInspectable var borderWidth: CGFloat = 2.0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat = 0.0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }

}
Vakas
источник
6
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 50, 200, 200)];

view.layer.backgroundColor = [UIColor whiteColor].CGColor;
view.layer.cornerRadius = 20.0;
view.layer.frame = CGRectInset(v.layer.frame, 20, 20);

view.layer.shadowOffset = CGSizeMake(1, 0);
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .25;

[self.view addSubview:view];
[view release];
Jorik
источник
Применение setMasksToBounds важно. Установка цвета фона и тени отсутствует.
djskinner
3

Swift 4 - Использование IBDesignable

   @IBDesignable
    class DesignableView: UIView {
    }

    extension UIView
    {

        @IBInspectable
        var cornerRadius: CGFloat {
            get {
                return layer.cornerRadius
            }
            set {
            layer.cornerRadius = newValue
        }
    }
}
Saranjith
источник
Извините, но как новичок в разработке IOS. Как решение препятствует layer.cornerRadiusвозвращению в исходное состояние? (например, как раскадровка xcode знает, как установить cornerRadiusтолько после UIViewинициализации оригинала )?
AlanSTACK
3
view.layer.cornerRadius = 25
view.layer.masksToBounds = true
Парт Баро
источник
3

- SwiftUI

В SwiftUI вы можете использовать cornerRadiusмодификатор прямо на любом, Viewчто захотите. Например, этот вопрос:

Text("Signing In…")
    .padding(16)
    .background(Color.red)
    .cornerRadius(50)

предварительный просмотр

Обратите внимание, что больше нет ромбовидного радиуса, поэтому, даже если вы установили угол угла более половины высоты , он будет плавно округляться.

Ознакомьтесь с этим ответом, чтобы узнать, как округлить определенные углы в SwiftUI

Мойтаба Хоссейни
источник
2

Пожалуйста, импортируйте, Quartzcore frameworkтогда вы должны установить setMaskToBoundsдля TRUEэтого очень важную строку.

Затем: [[yourView layer] setCornerRadius:5.0f];

DeveshM
источник
2
UIView* viewWithRoundedCornersSize(float cornerRadius,UIView * original)
{
    // Create a white border with defined width
    original.layer.borderColor = [UIColor yellowColor].CGColor;
    original.layer.borderWidth = 1.5;

    // Set image corner radius
    original.layer.cornerRadius =cornerRadius;

    // To enable corners to be "clipped"
    [original setClipsToBounds:YES];
    return original;
}
Ашиш Патель
источник
2

Сделайте это программно в obj c

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 50,    200, 200)];

view.layer.backgroundColor = [UIColor whiteColor].CGColor;
view.layer.cornerRadius = 20.0;
view.layer.frame = CGRectInset(v.layer.frame, 20, 20);

[view.layer.shadowOffset = CGSizeMake(1, 0);
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .25;][1]

[self.view addSubview:view];

Мы также можем сделать это из сториборда.

 layer.cornerRadius  Number  5

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

Викас Раджпут
источник
2

если закругленный угол не работает в viewDidload () , лучше написать код в viewDidLayoutSubview ()

-(void)viewDidLayoutSubviews
{
    viewTextfield.layer.cornerRadius = 10.0 ;                                               
    viewTextfield.layer.borderWidth = 1.0f;
    viewTextfield.layer.masksToBounds =  YES;
    viewTextfield.layer.shadowRadius = 5;
    viewTextfield.layer.shadowOpacity = 0.3;
    viewTextfield.clipsToBounds = NO;
    viewTextfield.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
}

Надеюсь это поможет!

Дхармеш Мансата
источник
0

Вы также можете использовать изображение:

UIImage *maskingImage = [UIImage imageNamed:@"bannerBarBottomMask.png"];
CALayer *maskingLayer = [CALayer layer];
maskingLayer.frame = CGRectMake(-(self.yourView.frame.size.width - self.yourView.frame.size.width) / 2
                                , 0
                                , maskingImage.size.width
                                , maskingImage.size.height);
[maskingLayer setContents:(id)[maskingImage CGImage]];
[self.yourView.layer setMask:maskingLayer];
Richy
источник
0

set cornerRadious Недвижимость для круглого просмотра

set masksToBounds Boolean Значение изображения не будет отображаться за пределами границы углового радиуса.

view.layer.cornerRadius = 5;

view.layer.masksToBounds = YES;
bhautikmewada191
источник
0

Использование расширения UIView:

extension UIView {    

func addRoundedCornerToView(targetView : UIView?)
{
    //UIView Corner Radius
    targetView!.layer.cornerRadius = 5.0;
    targetView!.layer.masksToBounds = true

    //UIView Set up boarder
    targetView!.layer.borderColor = UIColor.yellowColor().CGColor;
    targetView!.layer.borderWidth = 3.0;

    //UIView Drop shadow
    targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
    targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
    targetView!.layer.shadowOpacity = 1.0
}
}

Применение:

override func viewWillAppear(animated: Bool) {

sampleView.addRoundedCornerToView(statusBarView)

}
AG
источник
0

В Swift 4.2 и Xcode 10.1

let myView = UIView()
myView.frame = CGRect(x: 200, y: 200, width: 200, height: 200)
myView.myViewCorners()
//myView.myViewCorners(width: myView.frame.width)//Pass View width
view.addSubview(myView)

extension UIView {
    //If you want only round corners
    func myViewCorners() {
        layer.cornerRadius = 10
        layer.borderWidth = 1.0
        layer.borderColor = UIColor.red.cgColor
        layer.masksToBounds = true
    }
    //If you want complete round shape, enable above comment line
    func myViewCorners(width:CGFloat) {
        layer.cornerRadius = width/2
        layer.borderWidth = 1.0
        layer.borderColor = UIColor.red.cgColor
        layer.masksToBounds = true
    }
}
IOS
источник
-4

ON Xcode 6 Ваша попытка

     self.layer.layer.cornerRadius = 5.0f;

или

    self.layer.layer.cornerRadius = 5.0f;
    self.layer.clipsToBounds = YES;
Сарингхан Вунгсин
источник