Так что на самом деле это не так просто, как просто замаскировать наше изображение на UISwitch
.
Причина, по которой этот простой подход не сработает, заключается в том, как на самом деле работает маскировка.Когда мы маскируем изображение, которое вы предлагаете, мы принимаем форму другого вида и применяем его к нашему изображению.Затем наше изображение фактически добавляется к родителю.В итоге мы получаем изображение, обрезанное по форме нашего переключателя (это изображение не получает ни одного из событий переключателя).
То, что нам на самом деле нужно сделать, немного сложнее.Нам нужно добавить наше изображение к различным частям subview
s коммутатора и вместо этого замаскировать их.
Для удобства я создал собственный класс коммутатора, который выполняет тяжелую работу за кулисами.:
class ImageTintSwitch: UISwitch {
init(tintImage: UIImage) {
super.init(frame: .zero)
// Make sure we have subviews & grab the first one
guard let element = subviews.first else { return }
// Loop through only the subviews that clipToBounds inside the one we grabbed
for (index, view) in element.subviews.enumerated() where view.clipsToBounds {
// Add our image only where we need it
configure(with: tintImage, on: element, maskedTo: view, atIndex: index)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configure(with image: UIImage, on parent: UIView, maskedTo view: UIView, atIndex index: Int) {
// Make an imageView with our image
let imageView: UIImageView = {
let view = UIImageView(image: image)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// Insert our new imageView only where we need it
parent.insertSubview(imageView, at: index)
// Mask our imageView to the views that we found
imageView.mask = view
// Constrain our imageView to match the parent view
NSLayoutConstraint.activate([
imageView.centerXAnchor.constraint(equalTo: parent.centerXAnchor),
imageView.centerYAnchor.constraint(equalTo: parent.centerYAnchor),
imageView.widthAnchor.constraint(equalTo: parent.widthAnchor),
imageView.heightAnchor.constraint(equalTo: parent.heightAnchor)
])
}
}
Чтобы использовать этот пользовательский переключатель, мы можем просто использовать следующий код:
let customSwitch = ImageTintSwitch(tintImage: UIImage(named: "gradient.jpg") ?? UIImage())
Вот результат: