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

CALayer не изменяет размер с помощью Autolayout

Я создал индикатор выполнения, который будет использоваться в tableView, создав слой градиента. Он работает отлично.

iPhone5: enter image description here

Чтобы использовать приложение на нескольких устройствах, я создал UIView в Storyboard, пометил его и добавил ограничения. Однако, когда я использую приложение на iPhone 6, CALayer не изменяет размер.

iPhone6: enter image description here

Я нахожу это очень глупым, но неважно. Я огляделся и попытался понять, как это решить в течение нескольких месяцев, но я пришел к выводу. Знает ли ANYONE, как сделать CALayers изменением размера с помощью UIView? Любая помощь будет очень высоко ценится! Спасибо.

        progressBar =  cell.contentView.viewWithTag(3) as UIView!
        progressBar.layer.cornerRadius = 4
        progressBar.layer.masksToBounds = true


        // create gradient layer
        let gradient : CAGradientLayer = CAGradientLayer()

        // create color array
        let arrayColors: [AnyObject] = [
            UIColor (red: 255/255, green: 138/255, blue: 1/255, alpha: 1).CGColor,
            UIColor (red: 110/255, green: 110/255, blue: 118/255, alpha: 1).CGColor]

        // set gradient frame bounds to match progressBar bounds
        gradient.frame = progressBar.bounds

        // set gradient color array
        gradient.colors = arrayColors

        //Set progress(progressBar)
        var percentageCompleted = 0.6

        gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradient.locations = [percentageCompleted, percentageCompleted]
        gradient.endPoint = CGPoint(x: 1, y: 0.5)

        // replace base layer with gradient layer
        progressBar.layer.insertSublayer(gradient, atIndex: 0)
4b9b3361

Ответ 1

По умолчанию слой UIView изменяет размер с его представлением, но подсловы не (как вы узнали). Один из способов сделать эту работу - создать пользовательский класс представления, переместить код, который у вас есть на свой вопрос, и переопределить layoutSublayersOfLayer, где вы можете установить уровень градиента того же размера, что и представление. Поскольку этот код теперь находится в пользовательском классе, я также создал свойство percentCompleted (вместо локальной переменной) и добавил предложение willSet, поэтому внешний вид панели обновляется при изменении свойства percentCompleted.

class RDProgressView: UIView {

    private let gradient : CAGradientLayer = CAGradientLayer()

    var percentageCompleted: Double = 0.0 {
        willSet{
            gradient.locations = [newValue, newValue]
        }
    }

    override func awakeFromNib() {
        self.layer.cornerRadius = 4
        self.layer.masksToBounds = true

        // create color array
        let arrayColors: [AnyObject] = [
            UIColor (red: 255/255, green: 138/255, blue: 1/255, alpha: 1).CGColor,
            UIColor (red: 110/255, green: 110/255, blue: 118/255, alpha: 1).CGColor]

        // set gradient color array
        gradient.colors = arrayColors

        //Set progress(progressBar)
        gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradient.locations = [percentageCompleted, percentageCompleted]
        gradient.endPoint = CGPoint(x: 1, y: 0.5)

        self.layer.insertSublayer(gradient, atIndex: 0)
    }

    override func layoutSublayersOfLayer(layer: CALayer!) {
        super.layoutSublayersOfLayer(layer)
        gradient.frame = self.bounds
    }
}

В IB вы измените класс своего представления на RDProgressView (в моем примере), а в cellForRowAtIndexPath вам нужно будет только получить ссылку на представление и установить его свойство скомпонованное.

progressBar =  cell.contentView.viewWithTag(3) as RDProgressView! 
progressBar.percentageCompleted = 0.2

Ответ 2

В качестве альтернативы принятому ответу вы также можете изменить класс уровня просмотров CAGradientLayer. Уровень просмотров всегда будет изменен в соответствии с изменениями макета. Вы можете добиться этого путем подкласса UIView

class GradientView: UIView {
  override class func layerClass() -> AnyClass {
    return CAGradientLayer.self
  }
}

затем установите цвета

if let gradientLayer = gradientView.layer as? CAGradientLayer {
  gradientLayer.colors = arrayColors
}

Это меньше кода, чем добавление и поддержка подслоя, но может не соответствовать всем прецедентам.