#ios #swift #uibutton
#iOS #swift #uibutton
Вопрос:
Я создал пользовательский UIButton для программного использования в моем приложении. На одном экране он работает нормально. В другом случае фон не отображается. Я просмотрел много похожих вопросов, а также сравнил код с другим контроллером представления, в котором он используется, когда он работает, и нет никаких очевидных причин. Почему не отображается цвет фона?
Пользовательский класс кнопок
import Foundation
import UIKit
class PillButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
initializeButton()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initializeButton()
}
private func initializeButton() {
backgroundColor = UIColor.white
setTitleColor(UIColor(named: "pink"), for: .normal)
contentEdgeInsets = UIEdgeInsets.init(top: 16, left: 48, bottom: 16, right: 48)
translatesAutoresizingMaskIntoConstraints = false
}
override func layoutSubviews() {
super.layoutSubviews()
let height = frame.height / 2
layer.cornerRadius = height
}
}
Контроллер представления
import Foundation
import UIKit
import MaterialComponents
class EventViewController: BaseViewController {
private static let HORIZONTAL_PADDING: CGFloat = 16
private var confirmButton: PillButton!
private var unableToAttendButton: UILabel!
private var signedUpLabel: UILabel!
private var baseScrollView: UIScrollView!
var event: Event!
private var viewModel: EventViewModel = EventViewModel()
override func viewDidLoad() {
super.viewDidLoad()
createView()
}
override func createView() {
super.createView()
createConfirmButton()
}
private func createConfirmButton() {
confirmButton = PillButton()
let descriptionBottomGuide = UILayoutGuide()
baseScrollView.addSubview(confirmButton)
baseScrollView.addLayoutGuide(descriptionBottomGuide)
descriptionBottomGuide.topAnchor.constraint(equalTo: eventDescription.bottomAnchor).isActive = true
confirmButton.centerXAnchor.constraint(equalTo: baseScrollView.centerXAnchor).isActive = true
confirmButton.topAnchor.constraint(equalTo: descriptionBottomGuide.bottomAnchor, constant: 20).isActive = true
}
}
Комментарии:
1. Код кнопки выглядит нормально, но логика ViewController воспроизводится не полностью — возможно, вам следует предоставить код для создания baseScrollView и скриншот вашего результирующего макета (с неправильным цветом кнопки)
Ответ №1:
Опубликованный вами код содержит МНОГО информации, которую вы не предоставили, поэтому довольно сложно понять, что может происходить.
Тем не менее, у вас есть несколько проблем с вашим PillButton
классом:
- вы не должны вызывать
initializeButton
layoutSubviews()
- вы должны обновить радиус угла в
layoutSubviews()
- нет необходимости переопределять
setTitle
- нет необходимости устанавливать
layer
цвет фона, и вы уже установили цвет фона кнопки, поэтому нет необходимости устанавливать его снова.
Кроме того, в опубликованном вами коде вы нигде не устанавливаете заголовок кнопки.
Попробуйте заменить свой PillButton
класс на этот и посмотрите, получите ли вы лучшие результаты:
class PillButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
initializeButton()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initializeButton()
}
private func initializeButton() {
backgroundColor = Colors.black
setTitleColor(UIColor(named: "pink"), for: .normal)
contentEdgeInsets = UIEdgeInsets.init(top: 16, left: 48, bottom: 16, right: 48)
translatesAutoresizingMaskIntoConstraints = false
}
override func layoutSubviews() {
super.layoutSubviews()
// update corner radius here!
layer.cornerRadius = bounds.height / 2
}
}
Если вы этого не сделаете, вам нужно выполнить некоторую отладку остальной части вашего кода (который вы не опубликовали здесь), чтобы выяснить, что происходит.
Комментарии:
1. Я опубликовал весь код, который имеет какое-либо взаимодействие с PillButton
2. Отредактируйте неправильно, я пропустил одно место. В этом месте я устанавливал topAnchor другого представления как равный нижней привязке confirmButton. Это отбрасывало макет и приводило к тому, что цвет фона не отображался.
Ответ №2:
confirmButton = PillButton()
Я бы изучил этот фрагмент кода. Назначенные инициализаторы, те, у которых есть frame и coder, в пользовательском классе button вызывают initializeButton() , но вы не реализуете init(), чтобы сделать то же самое.
Я бы изменил его на confirmButton = PillButton(frame:)