Добавление настраиваемого альфа-канала цвета границы в инспектор атрибутов

У меня вопрос из 2 частей. Сначала я хотел бы добавить альфа-канал границы в качестве пользовательского атрибута, например, как показано на этом рисунке.

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

Но первое, что я заметил, это то, что для установки цвета границы необходимо использовать CGColor вместо UIColor, а CGColor.alpha доступен только для чтения.

Итак, я попытался использовать что-то подобное, но это не сработало.

@IBInspectable var borderAlpha: CGFloat {
    set {
        let borderCGColor = layer.borderColor
        var color = UIColor(cgColor: borderCGColor!)

        if (newValue < 0) {
            color = color.withAlphaComponent(0)
            layer.borderColor = color.cgColor
        } else if (newValue > 1) {
            color = color.withAlphaComponent(1)
            layer.borderColor = color.cgColor
        } else {
            color = color.withAlphaComponent(newValue)
            layer.borderColor = color.cgColor
        }
    }
    get {
        return layer.borderColor!.alpha
    }
}

Я получаю это в пользовательских атрибутах среды выполнения, но это не влияет.

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

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

Наконец, как второй вопрос, на стрелках, которые увеличивают или уменьшают значения, он прыгает на единицу, но в альфа-поле Xcode он прыгает только на 0,05 и не может опускаться ниже 0 или выше 1. Как я могу добавить этот вид функциональности для моих определяемых пользователем атрибутов среды выполнения?

EDIT Вот полный код расширения, который у меня есть для UIView, который работает для всего, кроме альфа-канала границы.

import UIKit

@IBDesignable extension UIView {

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

@IBInspectable var borderAlpha: CGFloat {
    set {
        let borderCGColor = layer.borderColor
        var color = UIColor(cgColor: borderCGColor!)

        if (newValue < 0) {
            color = color.withAlphaComponent(0)
            layer.borderColor = color.cgColor
        } else if (newValue > 1) {
            color = color.withAlphaComponent(1)
            layer.borderColor = color.cgColor
        } else {
            color = color.withAlphaComponent(newValue)
            layer.borderColor = color.cgColor
        }
    }
    get {
        return layer.borderColor!.alpha
    }
}

@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
    }
}

@IBInspectable var shadowColor: UIColor? {
    set {
        layer.shadowColor = newValue!.cgColor
    }
    get {
        if let color = self.layer.shadowColor {
            return UIColor(cgColor: color)
        } else {
            return nil
        }
    }
}

@IBInspectable var shadowOffset: CGSize {
    set {
        layer.shadowOffset = newValue
    }
    get {
        return layer.shadowOffset
    }
}

@IBInspectable var shadowRadius: CGFloat {
    set {
        layer.shadowRadius = newValue
    }
    get {
        return layer.shadowRadius
    }
}

@IBInspectable var shadowOpacity: Float {
    set {
        if (newValue < 0) {
            layer.shadowOpacity = 0
        } else if (newValue > 1) {
            layer.shadowOpacity = 1
        } else {
            layer.shadowOpacity = newValue
        }
    }
    get {
        return layer.shadowOpacity
    }
}
}

person Jason Brady    schedule 06.03.2017    source источник
comment
Ни один из ваших ключевых путей не может работать, потому что вы забыли включить layer в ключевой путь. Точно так же вид не имеет углового радиуса, цвета границы, ширины границы или альфа-канала границы; чтобы написать любой из них как проверяемый, вам понадобится сеттер для каждого из них, чтобы общаться с представлением layer.   -  person matt    schedule 06.03.2017
comment
О, у меня на самом деле все это работает. Извините, я сейчас включу полный код.   -  person Jason Brady    schedule 06.03.2017


Ответы (1)


Моя первая мысль заключается в том, что, вероятно, существует фундаментальная неопределенность в отношении ваших borderColor и borderAlpha относительно того, что будет оцениваться первым. об этом ничего не известно и не гарантируется, поэтому, если случится так, что borderAlpha будет установлено и тогда borderColor, borderAlpha не будут волшебным образом переоценены. Фактически взаимная зависимость здесь вносит неопределенность, которая может объяснять различие в нашем опыте. Поэтому может быть лучше просто установить альфу как часть цвета.

Мы можем предположить, что это может быть правильно, потому что ваш borderAlpha отлично работает для меня:

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

Мы можем догадаться, поскольку у вас это не работает, что эта разница случайна; Мне просто повезло в том, что мой borderAlpha был оценен, видимо, после моего borderColor, но рассчитывать на это, видимо, нельзя.

Кстати, у меня тоже работают ваши теневые атрибуты:

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

Вы наверняка заметили, что они не работают? Это из-за этой строки:

clipsToBounds = newValue > 0

Опять же, это может произойти в любое время и установить ваш clipsToBounds в false, тем самым отсекая тень. (Или, может быть, они были работать на вас, и опять же, это был просто вопрос удачи относительно порядка, в котором оценивались вещи; взаимная зависимость здесь заключается в том, что clipsToBounds устанавливается в cornerRadius, но влияет на тень .

Короче говоря, я думаю, что здесь мы узнаем, что вам нужно сохранять эти свойства ортогональными друг другу (независимыми).

person matt    schedule 06.03.2017
comment
Интересный. Я видел другой код (не включая альфа-канал границы), в котором предлагалось использовать класс, но я просто не был уверен, как это повлияет на мои объекты. Поскольку большинство из них наследуются от UIView, кажется, что все они получают код, который я добавил. Я просто не был уверен, что произойдет с UILabel, если я изменю его класс на собственный класс, созданный на основе UIView... нужно ли мне будет создавать отдельный класс для каждого объекта, чтобы использовать его тогда? - person Jason Brady; 06.03.2017
comment
Кстати, в вашем коде есть изъян; вам нужно удалить эту строку: clipsToBounds = newValue > 0 Она мешает работе вашего теневого кода. - person matt; 06.03.2017
comment
Наконец, как второй вопрос, на стрелках, которые увеличивают или уменьшают значения, он прыгает на единицу, но в альфа-поле Xcode он прыгает только на 0,05 и не может опускаться ниже 0 или выше 1. Как я могу добавить этот вид функциональности для моих определяемых пользователем атрибутов среды выполнения? Я почти уверен, что нет никакого способа. Это сделало бы большой запрос функции к Apple. - person matt; 06.03.2017
comment
О, еще одна мысль в отношении вашего первоначального вопроса. Нет ли фундаментальной неопределенности в отношении ваших borderColor и borderAlpha относительно того, что будет оцениваться первым? Об этом ничего не известно и не гарантируется, поэтому, если случится так, что будет установлено borderAlpha, а затем borderColor, borderAlpha не будет волшебным образом переоценено. Фактически взаимная зависимость здесь вносит неопределенность, которая может объяснять различие в нашем опыте. Поэтому может быть лучше просто установить альфу как часть цвета. - person matt; 06.03.2017
comment
На самом деле я тоже об этом думал, я думаю, вы, вероятно, правы, лучше сделать это в селекторе цвета. - person Jason Brady; 06.03.2017
comment
Я лучше добавлю это к моему ответу. - person matt; 06.03.2017
comment
Хорошо, я полностью переработал свой ответ, включив в него некоторые комментарии и убрав информацию о расширении. - person matt; 06.03.2017