Можно ли установить свойства границы UIView из конструктора интерфейса?

184

Можно ли управлять свойствами границ UIView (цвет, толщина и т. Д.) Непосредственно из конструктора интерфейса, или я могу сделать это только программно?

matteo.cajani
источник
Проверьте это http://stackoverflow.com/a/28854514/3177007
Мохамед Джалил Назир
1
На всякий случай, если кто-нибудь придет из Google, как я. Чтобы увидеть, как эти изменения отражаются в IB, вам просто нужно создать подкласс UIView и назначить его любому представлению, которым вы хотите манипулировать в IB.
Kanongata

Ответы:

392

На самом деле вы можете установить некоторые свойства слоя представления через конструктор интерфейса. Я знаю, что я могу установить borderWidth и cornerRadius слоя через xcode. borderColor не работает, вероятно, потому что слой хочет CGColor вместо UIColor.

Возможно, вам придется использовать строки вместо чисел, но это работает!

layer.cornerRadius
layer.borderWidth
layer.borderColor

Обновление: layer.masksToBounds = true

пример

Обновление: выберите соответствующий тип для Keypath:

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

Rich86man
источник
3
Вам и Питеру ДеВису: я использую Xcode 4.6.3 и могу установить тип ключевого пути на «Color» без реализации интерфейса
39
К сожалению layer.borderColor не может быть установлен таким образом. Это CGColorRef, но этот тип значения IB Color - UIColor.
mrgrives
12
Это то, что делает пользовательские атрибуты времени выполнения! Ха-ха, я пишу для iOS с 2011 года, и я так и не узнал, для чего эти поля. Спасибо за этот потрясающий ответ.
Энди Ибанез,
3
Хорошо, но вы должны установить правильный тип для каждого свойства. Например, тип "layer.cornerRadius" должен быть установлен на "Number" вместо "String"!
Питер Крейнз
5
Кроме того, не забудьте установить флажок «закрепить за границами», чтобы угол работал.
Пьер-Оливье Симонар
183

Ответ Rich86Man верен, но вы можете использовать категории для прокси-свойств, таких как layer.borderColor. (От обычного C CocoaPod)

CALayer + XibConfiguration.h:

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>

@interface CALayer(XibConfiguration)

// This assigns a CGColor to borderColor.
@property(nonatomic, assign) UIColor* borderUIColor;

@end

CALayer + XibConfiguration.m:

#import "CALayer+XibConfiguration.h"

@implementation CALayer(XibConfiguration)

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

-(UIColor*)borderUIColor
{
    return [UIColor colorWithCGColor:self.borderColor];
}

@end

Интерфейсный Разработчик

layer.borderUIColor

Результат будет очевиден во время выполнения, а не в Xcode.

Изменить : Вам также нужно установить layer.borderWidthпо крайней мере 1, чтобы увидеть границу с выбранным цветом.

В Swift 2.0:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.CGColor
        }

        get {
            return UIColor(CGColor: self.borderColor!)
        }
    }
}

В Swift 3.0:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.cgColor
        }

        get {
            return UIColor(cgColor: self.borderColor!)
        }
    }
}
Питер ДеВиз
источник
Я не могу заставить это работать на меня. Файл .m жалуется на то, что borderColor должен быть borderUIColor и исправлять его, после этого он по-прежнему показывает предупреждения, а цвет границы не отображается во время выполнения. Бит, который отличается от моего, это то, что у меня @ реализация NameOfFile, а не @ реализация CALayer (NameOfFile), я не понимаю, часть CALayer, не могли бы вы объяснить, пожалуйста
Дэйв Хей,
2
@PeterDeWeese great answer! =)
c-злодей
1
На самом деле вы можете использовать Number с borderWidth и принять NSNumber. Работает нормально.
Питер ДеВиз
1
Это, безусловно, лучшее решение, на мой взгляд, для решения проблемы BorderColor. Фантастическое использование категорий!
EricWasTaken
1
Работал в Swift!
Котиос
81

Аналогичный ответ на вопрос iHulk, но в Swift

Добавьте файл с именем UIView.swift в свой проект (или просто вставьте его в любой файл):

import UIKit

@IBDesignable extension UIView {
    @IBInspectable var borderColor: UIColor? {
        set {
            layer.borderColor = newValue?.cgColor
        }
        get {
            guard let color = layer.borderColor else {
                return nil
            }
            return UIColor(cgColor: color)
        }
    }
    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }
    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
            clipsToBounds = newValue > 0
        }
        get {
            return layer.cornerRadius
        }
    }
}

Тогда это будет доступно в Интерфейсном Разработчике для каждой кнопки, imageView, метки и т. Д. В Панели утилит> Инспектор атрибутов:

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

Примечание: граница появится только во время выполнения.

Аксель Гильмин
источник
@Gaurav Какую ошибку вы видите? На каком компоненте (UIButton, UILabel и т. Д.) Вы его используете?
Аксель Гильмин
Я не могу помочь вам без подробностей :(
Аксель Гильмин
2
Я получал сбой Интерфейсного Разработчика с таким подходом, пока я не удалил @IBDesignableс начала расширения.
Альберт Бори
1
Это удивительно ... Спасибо! Я использую XCode 8.2.1
bobwki
1
Очень удобно и аккуратно! Спасибо!
Карл-Джон Чоу
56

Вы можете создать категорию UIView и добавить ее в .h файл категории

@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;

Теперь добавьте это в файл .m

@dynamic borderColor,borderWidth,cornerRadius;

и это тоже в. м файл

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

-(void)setBorderWidth:(CGFloat)borderWidth{
    [self.layer setBorderWidth:borderWidth];
}

-(void)setCornerRadius:(CGFloat)cornerRadius{
    [self.layer setCornerRadius:cornerRadius];
}

теперь вы увидите это в вашей раскадровке для всех подклассов UIView (UILabel, UITextField, UIImageView и т. д.)

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

Вот и все .. Нет необходимости импортировать категорию куда угодно, просто добавьте файлы категории в проект и посмотрите эти свойства в раскадровке.

iHulk
источник
2
Дополните его IB_DESIGNABLE, чтобы IB перерисовал ваш пользовательский вид, используя drawRect: метод developer.apple.com/library/ios/recipes/…
txulu
3
Это здорово, если вы напишите IB_DESIGNABLE в файле .h перед строкой интерфейса, вам не нужно добавлять строку @dynamic в .m
Jasmeet
@ user1618612 это не имеет никакого отношения к разрешению, это просто установка нормальных свойств слоя.
iHulk
11

Для Swift 3 и 4 , если вы хотите использовать IBInspectables, вот что:

@IBDesignable extension UIView {
    @IBInspectable var borderColor:UIColor? {
        set {
            layer.borderColor = newValue!.cgColor
        }
        get {
            if let color = layer.borderColor {
                return UIColor(cgColor: color)
            }
            else {
                return nil
            }
        }
    }
    @IBInspectable var borderWidth:CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }
    @IBInspectable var cornerRadius:CGFloat {
        set {
            layer.cornerRadius = newValue
            clipsToBounds = newValue > 0
        }
        get {
            return layer.cornerRadius
        }
    }
}
RamwiseMatt
источник
Это лучшее решение для меня
Mục Đồng
Отличное решение, спасибо
Ebtehal___
7

хотя это может устанавливать свойства, на самом деле это не отражается в IB. Так что, если вы по сути пишете код в IB, вы можете сделать это в исходном коде.

Зайин Криге
источник
1
Добро пожаловать в MVC! Вы просматриваете свойства никогда не должны быть в коде!
Алехандро Иван
2
^ Это не то, что MVC.
Эндрю Пламмер
1
Учитывая, что 95% времени этот код поступает в контроллер, это также MVC, конечно, если вы должным образом
Daniele Bernardini
4

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

Мэтью Кирос
источник
10
Обходные пути экономят время сейчас и тратят гораздо больше времени в будущем.
Лачезар Тодоров
0

Это абсолютно возможно только тогда, когда вы сидите layer.masksToBounds = trueи отдыхаете.

Сунил Тардж
источник
-1

Раскадровка не работает для меня все время, даже после того, как вы попробуете все решения здесь

Так что это всегда идеальный ответ, используя код, просто создайте экземпляр IBOutlet из UIView и добавьте свойства

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

layer.cornerRadius = 10
layer.borderWidth = 1
layer.borderColor = UIColor.blue.cgColor

Длинный ответ:

Закругленные углы UIView / UIButton и т. Д.

customUIView.layer.cornerRadius = 10

Толщина границы

pcustomUIView.layer.borderWidth = 2

Цвет границы

customUIView.layer.borderColor = UIColor.blue.cgColor
swiftBoy
источник
Вопрос очень конкретный и спросите, как это сделать из Интерфейсного Разработчика. Ваш ответ не имеет значения.
Shinnyx
-5

Пожалуйста, добавьте эти 2 простые строки кода:

self.YourViewName.layer.cornerRadius = 15
self.YourViewName.layer.masksToBounds = true

Это будет работать нормально.

Снеха Патил
источник