Cocoa Touch: Как изменить цвет и толщину границы UIView?

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

Спасибо

Ответ 1

Чтобы установить свойство border, вам нужно использовать слой вида. например:

#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;

Вам также необходимо связать с QuartzCore.framework доступ к этой функции.

Ответ 2

Обновление Xcode 6

Поскольку новая версия Xcode имеет лучшее решение:

С помощью @IBInspectable вы можете установить атрибуты непосредственно из Attributes Inspector.

My Custom View @IBInspectable Attributes

Это устанавливает для вас User Defined Runtime Attributes:

enter image description here

Существует два подхода к настройке:

Вариант 1 (с живым обновлением в раскадровке)

  • Создать MyCustomView.
  • Наследует от UIView.
  • Установить @IBDesignable (это делает обновление в реальном времени обновленным). *
  • Задайте свои атрибуты времени выполнения (граница и т.д.) с помощью @IBInspectable
  • Измените класс Views на MyCustomView
  • Изменить в панели "Атрибуты" и увидеть изменения в раскадровке:)

`

@IBDesignable
class MyCustomView: UIView {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.CGColor
        }
    }
}

* @IBDesignable работает только при установке в начале class MyCustomView

Вариант 2 (не работает со Swift 1.2, см. комментарии)

Расширьте свой класс UIView:

extension UIView {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.CGColor
        }
    }
}

Таким образом, в вашем представлении по умолчанию всегда есть эти дополнительные редактируемые поля в Attributes Inspector. Другим преимуществом является то, что вам не нужно каждый раз менять класс на MyCustomView. Однако одним из недостатков этого является то, что вы будете видеть свои изменения только при запуске приложения.

Ответ 3

Вы также можете создать границу с цветом вашего желания.

view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;

* r, g, b - значения от 0 до 255.

Ответ 4

Добавьте следующие @IBInspectables в расширение UIView

extension UIView {

  @IBInspectable var borderWidth: CGFloat {
    get {
      return layer.borderWidth
    }
    set(newValue) {
      layer.borderWidth = newValue
    }
  }

  @IBInspectable var borderColor: UIColor? {
    get {
      if let color = layer.borderColor {
        return UIColor(CGColor: color)
      }
      return nil
    }
    set(newValue) {
      layer.borderColor = newValue?.CGColor
    }
  }
}

И тогда вы должны иметь возможность устанавливать атрибуты borderColor и borderWidth непосредственно из Attribute inspector. См. Прикрепленное изображение

Инспектор атрибутов

Ответ 5

Когда я использую решение Vladimir CALayer, а поверх представления у меня есть анимация, например, модальное отклонение UINavigationController, я вижу, что происходит множество сбоев и возникают проблемы с производительностью.

Итак, еще один способ добиться этого, но без сбоев и потери производительности - создать пользовательский UIView и реализовать сообщение drawRect следующим образом:

- (void)drawRect:(CGRect)rect
{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(contextRef, 1);
    CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
    CGContextStrokeRect(contextRef, rect);    
}

Ответ 6

Попробуйте этот код:

view.layer.borderColor =  [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];

Ответ 7

view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor

Ответ 8

Я бы не предложил переопределить drawRect из-за того, что вы поразили производительность.

Вместо этого я бы изменил свойства класса, как показано ниже (в вашем пользовательском uiview):

  - (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
      self.layer.borderWidth = 2.f;
      self.layer.borderColor = [UIColor redColor].CGColor;
    }
  return self;

Я не видел никаких сбоев при приеме выше подхода - не знаю, почему вставка initWithFrame останавливает их; -)

Ответ 9

Я хотел добавить это в ответ @marczking (Вариант 1) в качестве комментария, но мой низкий статус в StackOverflow предотвращает это.

Я сделал порт ответа @marczking на Objective C. Работает как шарм, спасибо @marczking!

UIView + Border.h:

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface UIView (Border)

-(void)setBorderColor:(UIColor *)color;
-(void)setBorderWidth:(CGFloat)width;
-(void)setCornerRadius:(CGFloat)radius;

@end

UIView + Border.m:

#import "UIView+Border.h"

@implementation UIView (Border)
// Note: cannot use synthesize in a Category

-(void)setBorderColor:(UIColor *)color
{
    self.layer.borderColor = color.CGColor;
}

-(void)setBorderWidth:(CGFloat)width
{
    self.layer.borderWidth = width;
}

-(void)setCornerRadius:(CGFloat)radius
{
    self.layer.cornerRadius = radius;
    self.layer.masksToBounds = radius > 0;
}

@end

Ответ 10

@BIInspectable работает для меня на iOS 9, Swift 2.0

extension UIView {

@IBInspectable var borderWidth: CGFloat {
get {
        return layer.borderWidth
    }
    set(newValue) {
        layer.borderWidth = newValue
    }
}

@IBInspectable var cornerRadius: CGFloat {
    get {
        return layer.cornerRadius
    }
    set(newValue) {
        layer.cornerRadius = newValue
    }
}

@IBInspectable var borderColor: UIColor? {
    get {
        if let color = layer.borderColor {
            return UIColor(CGColor: color)
        }
        return nil
    }
    set(newValue) {
        layer.borderColor = newValue?.CGColor
    }
}

Ответ 11

Если вы не хотите редактировать слой UIView, вы всегда можете вставлять представление в другое представление. Родительский вид будет иметь цвет фона, соответствующий цвету границы. Это также будет немного больше, в зависимости от того, насколько широка ваша граница.

Конечно, это работает только в том случае, если ваше представление не прозрачно, и вам нужен только один цвет границы. OP хотел, чтобы граница была в самом представлении, но это может быть жизнеспособной альтернативой.

Ответ 12

Если вы хотите добавить другую границу с разных сторон, возможно, добавить подвью с конкретным стилем - это легко найти.

Ответ 13

Цвет границы элемента в Swift 4.2:

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell_lastOrderId") as! Cell_lastOrder
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.white.cgColor
cell.layer.cornerRadius = 10