Пользовательский цвет фона UIButton не работает

#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:)