Этот вопрос касается Swift 4, Xcode 9.3.1.
Процесс изменения цвета кнопки изображения хорошо документирован.Это не проблема.
Этот вопрос касается ПОЧЕМУ цвет кнопки изображения сбрасывается на цвет по умолчанию, если кнопка оказывается целью внутри IBAction
, и что делать соб этом.
Я создал новый проект в XCode, чтобы продемонстрировать то, что я вижу.Это проект, имеющий IBAction в контроллере представления, который пытается изменить цвет изображений на кнопке.Я добавил в приложение три кнопки (oneButton
, twoButton
, threeButton
) и связал их, чтобы у каждой из них были следующие выходы:
Для каждой кнопки определено другое изображение.Вот пример:
А вот ViewController
:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
@IBOutlet weak var threeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func myAction(sender: UIButton) {
let oneImageView = oneButton.imageView
if sender == oneButton {
print("oneButton")
oneImageView?.setImageColor(color: UIColor.red)
} else if sender == twoButton {
print("twoButton")
oneImageView?.setImageColor(color: UIColor.blue)
} else if sender == threeButton {
print("threeButton")
oneImageView?.setImageColor(color: UIColor.purple)
}
}
}
extension UIImageView {
func setImageColor(color: UIColor) {
let templateImage = self.image?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
self.image = templateImage
self.tintColor = color
}
}
При нажатии на каждый значок отображается соответствующий текст вОкно вывода (oneButton
, twoButton
, threeButton
), в зависимости от того, какое из них было нажато.Это работает нормально.
При запуске приложения цвет первого изображения черный (по умолчанию), как и ожидалось.
При нажатии twoButton
цвет на первом изображении изменяется насиний, как и ожидалось.
Нажатие threeButton
вызывает изменение цвета на первом изображении на фиолетовый, как и ожидалось.
Нажатие oneButton
приводит к сбросу цвета на первом изображении напо умолчанию (черный).Это НЕ ожидается.
Я думаю, что происходит, потому что, поскольку кнопка в настоящее время обрабатывает системное событие (касание), цвет, который я устанавливаю, стирается из-занекоторый системный процесс.
Я изменил код так, чтобы вместо Touch Up Inside
, myAction()
был вызван Touch Down
, и цвет первого изображения стал красным!Но только при прикосновении ... как только я отпустил, цвет вернулся к значению по умолчанию.
Я хотел бы иметь возможность прикоснуться к oneButton
и изменить его на любой цвет в кодеи не изменяйте его по умолчанию на цвет.
ADDITION / EDIT
Приведенный выше код снова и снова устанавливает режим рендеринга изображения.Я понимаю, что не должно быть необходимым для этого.Но когда я этого не делал, цвета не менялись, когда приложение запускалось в симуляторе.Код выше, по крайней мере, меняет цвет изображения, если к нему не прикасаться.В приведенном ниже коде, хотя соответствующая часть if / else в myAction()
выполняется, настройка .tintColor
не оказывает никакого влияния, независимо от того, по какому элементу щелкнули.Я пробовал с experiment
true и false, но безрезультатно.
class ViewController: UIViewController {
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
@IBOutlet weak var threeButton: UIButton!
var oneImageView: UIImageView!
var oneImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
oneImageView = oneButton.imageView
oneImage = oneImageView?.image
let experiment = true
if experiment {
oneImageView?.image = UIImage(named: "image")?.withRenderingMode(.alwaysTemplate)
} else {
oneImage.withRenderingMode(.alwaysTemplate)
oneImageView.image = oneImage
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func myAction(sender: UIButton) {
//let oneImageView = oneButton.imageView
let tintColor: UIColor = {
print("switch doesn't work here for some reason")
if sender == oneButton {
print("oneButton")
return .red
} else if sender == twoButton {
print("twoButton")
return .blue
} else if sender == threeButton {
print("threeButton")
return .purple
} else {
return .cyan
}
}()
oneImageView?.tintColor = tintColor
}
}