У меня есть класс и расширение для UIButton
. Пользовательский класс, убирающий заголовок и отображающий индикатор загрузки по клику (LoadingButton
). - Расширение, объявляющее пользовательскую функцию для применения градиента к кнопке и т. д.
Оба работают, но вызов функции typeMain()
для кнопки класса LoadingButton
связан с проблемой — заголовок кнопки не удаляется, поэтому кнопка загрузки отображается поверх заголовка.
Как я могу объединить оба решения этой проблемы?
Кстати: button.typeMain()
вызывают viewDidLoad()
.
Кнопка загрузки:
class LoadingButton: UIButton {
var originalButtonText: String?
var activityIndicator: UIActivityIndicatorView!
func showLoading() {
originalButtonText = self.titleLabel?.text
self.setTitle("", for: .normal)
if (activityIndicator == nil) {
activityIndicator = createActivityIndicator()
}
showSpinning()
}
func hideLoading() {
self.setTitle(originalButtonText, for: .normal)
activityIndicator.stopAnimating()
}
private func createActivityIndicator() -> UIActivityIndicatorView {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.hidesWhenStopped = true
activityIndicator.color = .white
return activityIndicator
}
private func showSpinning() {
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(activityIndicator)
centerActivityIndicatorInButton()
activityIndicator.startAnimating()
}
private func centerActivityIndicatorInButton() {
let xCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: activityIndicator, attribute: .centerX, multiplier: 1, constant: 0)
self.addConstraint(xCenterConstraint)
let yCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: activityIndicator, attribute: .centerY, multiplier: 1, constant: 0)
self.addConstraint(yCenterConstraint)
}
Расширение для настройки каждой кнопки:
extension UIButton {
func typeMain() {
self.translatesAutoresizingMaskIntoConstraints = false
let height = UIScreen.main.bounds.height * 0.07
let width = UIScreen.main.bounds.width * 0.9
self.heightAnchor.constraint(equalToConstant: height).isActive = true
self.widthAnchor.constraint(equalToConstant: width).isActive = true
layoutIfNeeded()
self.addCharacterSpacing()
self.tintColor = UIColor.white
let color = UIColor(red: 11/255, green: 95/255, blue: 244/255, alpha: 1)
let sndColor = UIColor(red: 106/255, green: 178/255, blue: 255/255, alpha: 1)
self.layer.cornerRadius = self.frame.size.height / 5.0
self.applyGradient(colours: [color, sndColor], locations: [0.0, 1.0])
let shadowSize : CGFloat = 2.0
self.layer.shadowColor = UIColor(red: 106/255, green: 178/255, blue: 255/255, alpha: 1).cgColor
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
self.layer.shadowOpacity = 0.4
let shadowPath = UIBezierPath(rect: CGRect(x: -shadowSize / 2,
y: shadowSize,
width: self.frame.size.width + shadowSize,
height: self.frame.size.height + shadowSize))
self.layer.shadowPath = shadowPath.cgPath
self.layer.shadowRadius = 5
self.layer.masksToBounds = false
}
Расстояние между символами
extension UILabel {
func addCharacterSpacing(kernValue: Double = 0.5) {
if let labelText = text, labelText.count > 0 {
let attributedString = NSMutableAttributedString(string: labelText)
attributedString.addAttribute(NSAttributedString.Key.kern, value: kernValue, range: NSRange(location: 0, length: attributedString.length - 1))
attributedText = attributedString
}
}
Показать addCharacterSpacing
метод
@RajeshKumarR см. редактирование.
В вашем пользовательском классе используется заголовок кнопки, а в методе расширения — кнопка с атрибутомTitle. Обновите свой собственный класс, чтобы сохранить ссылку на attributeTitle.
class LoadingButton: UIButton {
var originalButtonText: String?
var attributedButtonText: NSAttributedString?
var activityIndicator: UIActivityIndicatorView!
func showLoading() {
originalButtonText = self.titleLabel?.text
attributedButtonText = self.attributedTitle(for: .normal)
self.setTitle("", for: .normal)
self.setAttributedTitle(NSAttributedString(string: ""), for: .normal)
if (activityIndicator == nil) {
activityIndicator = createActivityIndicator()
}
showSpinning()
}
func hideLoading() {
self.setAttributedTitle(attributedButtonText, for: .normal)
self.setTitle(originalButtonText, for: .normal)
activityIndicator.stopAnimating()
}
}
К сожалению, это не удалит заголовок кнопки при выполнении showLoading()
.
IIRC
viewDidLoad
вызывается только один раз для экземпляраUIViewController
. Достаточно ли этого для ваших потребностей/ожиданий использования функцииtypeMain
в вашем расширении? Мне кажется, что вам нужен собственный подклассUIView
(а не подклассUIButton
), который работает как кнопка, но делает совсем другие вещи.