Градиент градиента UIButton с угловым радиусом

Я написал код, который работает на iPhone X, но не работает на iPhone SE. Вот что у нас на iPhone SE

У кого-нибудь есть идеи, почему он правильно работает на iPhone X, а не на iPhone SE.

Я вызываю эту функцию в viewDidLayoutSubviews ()

extension UIView {
    enum Direction {
        case horizontal
        case vertical
    }

    func addGradient(cornerRadius: CGFloat, colors: [UIColor], lineWidth: CGFloat, direction: Direction) {
       self.layer.cornerRadius = cornerRadius
        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = colors.map({ (color) -> CGColor in
            color.cgColor
        })

        switch direction {
        case .horizontal:
            gradient.startPoint = CGPoint(x: 0, y: 1)
            gradient.endPoint = CGPoint(x: 1, y: 1)
        case .vertical:
            gradient.startPoint = CGPoint(x: 0, y: 0)
            gradient.endPoint = CGPoint(x: 0, y: 1)
        }

        var shadowLayer: CAShapeLayer!
        shadowLayer = CAShapeLayer()
        shadowLayer.lineWidth = lineWidth
        shadowLayer.path = UIBezierPath(roundedRect: self.bounds.insetBy(dx: lineWidth, dy: lineWidth), cornerRadius: cornerRadius).cgPath
        shadowLayer.fillColor = nil
        shadowLayer.strokeColor = UIColor.black.cgColor
        gradient.mask = shadowLayer
        self.layer.addSublayer(gradient)
    }
}

Когда вы вызываете эту функцию addGradient?

André Slotta 27.09.2018 12:36

@ AndréSlotta в viewDidLayoutSubviews ()

Artem Sidorenko 27.09.2018 12:37

Вы можете показать этот код viewDidLayoutSubviews?

André Slotta 27.09.2018 12:38

Полагаю, что addGradient() вызывается дважды. Это делается правильным методом (после того, как макет был выполнен), но вы должны удалить слой, если он был раньше, чтобы избежать двойной проблемы (или исправить другую проблему, из-за которой он вызывается дважды).

Larme 27.09.2018 12:38

@ AndréSlotta serversButtonOutlet.addGradient (cornerRadius: 31.0, цвета: [UIColor (красный: 49/256, зеленый: 211/256, синий: 179/256, альфа: 1.0), UIColor (красный: 68/256, зеленый: 164 / 256, синий: 214/256, альфа: 1.0)], lineWidth: 2.0, направление: .horizontal)

Artem Sidorenko 27.09.2018 12:41

@Larme мы добавили проверочный код (см. Ответ ниже), но он не работает ...

Artem Sidorenko 27.09.2018 13:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
54
1

Ответы 1

Поскольку viewDidLayoutSubviews вызывается несколько раз, вам нужно убедиться, что вы создали слой градиента только один раз. Добавьте такой чек:

func addGradient(cornerRadius: CGFloat, colors: [UIColor], lineWidth: CGFloat, direction: Direction) {
    self.layer.cornerRadius = cornerRadius

    if let gradient = self.layer.sublayers?.last as? CAGradientLayer {
        // gradient layer already exists - update its frame
        gradient.frame = bounds
    } else {
        // gradient layer does not exist yet - create it
        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = colors.map({ (color) -> CGColor in
            color.cgColor
        })

        switch direction {
        case .horizontal:
            gradient.startPoint = CGPoint(x: 0, y: 1)
            gradient.endPoint = CGPoint(x: 1, y: 1)
        case .vertical:
            gradient.startPoint = CGPoint(x: 0, y: 0)
            gradient.endPoint = CGPoint(x: 0, y: 1)
        }

        var shadowLayer: CAShapeLayer!
        shadowLayer = CAShapeLayer()
        let rectPath = UIBezierPath(roundedRect: self.bounds.insetBy(dx: lineWidth, dy: lineWidth), cornerRadius: cornerRadius).cgPath
        shadowLayer.path = rectPath
        shadowLayer.lineWidth = lineWidth
        shadowLayer.fillColor = nil
        shadowLayer.strokeColor = UIColor.black.cgColor
        gradient.mask = shadowLayer
        self.layer.addSublayer(gradient)
    }
}

Другие вопросы по теме