Вместо использования обычной кнопки я вложил в подкласс UIControl
, потому что мне нужно было добавить к нему градиент.У меня также есть способ добавить тень и индикатор активности (не виден на изображении ниже) в качестве кнопки с отслеживанием состояния, чтобы пользователи не нажимали кнопку, если (например) выполняется вызов API.
Этобыло действительно сложно попытаться заставить UIControl
вращаться, и чтобы сделать это, я добавил тень как отдельное представление к представлению контейнера, содержащему UIControl
, чтобы тень могла быть добавлена.
Теперь проблема в том, что элемент управления не ведет себя совсем как представление о вращении - позвольте мне показать вам скриншот для контекста:
Это середина вращения, но это простоо видимом для глаза - изображение показывает, что Градиент составляет 75% от длины синего UIView
на изображении.
https://github.com/stevencurtis/statefulbutton
ВЧтобы выполнить это вращение, я удаляю shadowview
, а затем изменяю рамку градиентной рамки на ее границы, и в этом проблема.
func viewRotated() {
CATransaction.setDisableActions(true)
shadowView!.removeFromSuperview()
shadowView!.frame = self.frame
shadowView!.layer.masksToBounds = false
shadowView!.layer.shadowOffset = CGSize(width: 0, height: 3)
shadowView!.layer.shadowRadius = 3
shadowView!.layer.shadowOpacity = 0.3
shadowView!.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 20, height: 20)).cgPath
shadowView!.layer.shouldRasterize = true
shadowView!.layer.rasterizationScale = UIScreen.main.scale
self.gradientViewLayer.frame = self.bounds
self.selectedViewLayer.frame = self.bounds
CATransaction.commit()
self.insertSubview(shadowView!, at: 0)
}
Так что этот метод вращения вызывается через родительский контроллер представления:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { context in
context.viewController(forKey: UITransitionContextViewControllerKey.from)
//inform the loginButton that it is being rotated
self.loginButton.viewRotated()
}, completion: { context in
// can call here when completed the transition
})
}
IЯ знаю, что это проблема, и я думаю, что это не происходит в нужное время, чтобы действовать так же, как UIView
.Теперь проблема в том, что я пытался много вещей, чтобы заставить это работать, и мое лучшее решение (выше) не совсем там.
Бесполезно предлагать использовать UIButton
, чтобы использоватьизображение для градиента (пожалуйста, не предлагайте использовать изображение градиента в качестве фона для UIButton, я пробовал это) или стороннюю библиотеку.Это моя работа, она работает, но не работает для меня приемлемо, и я хочу, чтобы она работала так же, как и обычный взгляд (или, по крайней мере, знаю, почему нет).Я пробовал и другие решения выше, и пошел на свой UIControl
.Я знаю, что могу заблокировать представление, если есть вызов API, или использовать другие способы, чтобы пользователь не нажимал кнопку слишком много раз.Я пытаюсь исправить свое решение, а не придумывать способы обойти эту проблему с помощью CAGradientLayer
.
Проблема : мне нужно сделать UIControlView
с CAGradientLayer
в качестве фона вращайтесь так же, как UIView
, и не демонстрируйте проблему, показанную на изображении выше.
Полный пример: https://github.com/stevencurtis/statefulbutton