考虑以下内置Assert:
button.isSelected = true button.setImage(nil, for: .selected) assert(button.image(for: .selected) === nil) //^^^^^^^^^^^^^^ this trips with === and ==
字符串为什么?我的假设是错误的吗?
mzillmmw1#
Apple的docs:
讨论
在将图像关联到按钮时,至少应始终为正常状态设置一个图像。如果未为其他状态指定图像,则按钮将使用与正常状态关联的图像。如果未为正常状态指定图像,则按钮将使用系统值。目前尚不清楚的是,呼吁:
button.setImage(nil, for: .selected)
字符串也可以读作:“未指定.selected状态的映像"。因此,按钮将使用来自.normal的图像。如果您想在将按钮状态设置为.selected时删除图像:
.selected
.normal
button.isSelected = true button.setImage(nil, for: .normal) button.setImage(nil, for: .selected)
型下面是一些示例代码:
class SelectedButtonVC: UIViewController { let button = UIButton() var toggles: [UISwitch] = [] var imgs: [String : UIImage] = [:] let titles: [String] = [ "Normal", "Highlighted", "Selected", ] override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground var promptLabel: UILabel! var vSep: UIView! var hs: UIStackView! let stack = UIStackView() stack.axis = .vertical stack.spacing = 8 let colors: [UIColor] = [ .systemBlue, .systemRed, .systemGreen, ] let states: [UIControl.State] = [ .normal, .highlighted, .selected, ] let largeConfig = UIImage.SymbolConfiguration(pointSize: 40, weight: .bold, scale: .large) for (t, c) in zip(titles, colors) { guard let f = t.first?.description else { fatalError() } guard let img = UIImage(systemName: "\(f.lowercased()).square.fill", withConfiguration: largeConfig)?.withTintColor(c, renderingMode: .alwaysOriginal) else { fatalError("Could not load system image for \(t.lowercased())") } imgs[t] = img } for (t, s) in zip(titles, states) { button.setTitle(t, for: s) button.setImage(imgs[t], for: s) } for (c, s) in zip(colors, states) { button.setTitleColor(c, for: s) } button.backgroundColor = UIColor(white: 0.9, alpha: 1.0) button.layer.cornerRadius = 8 button.layer.borderWidth = 1 promptLabel = UILabel() promptLabel.text = "This is a button..." stack.addArrangedSubview(promptLabel) stack.addArrangedSubview(button) stack.setCustomSpacing(20.0, after: button) vSep = UIView() vSep.backgroundColor = .gray vSep.heightAnchor.constraint(equalToConstant: 2.0).isActive = true stack.addArrangedSubview(vSep) hs = UIStackView() hs.spacing = 8 hs.alignment = .center promptLabel = UILabel() promptLabel.text = "Toggle button.isSelected:" hs.addArrangedSubview(promptLabel) let sw = UISwitch() sw.isOn = false toggles.append(sw) hs.addArrangedSubview(sw) stack.addArrangedSubview(hs) vSep = UIView() vSep.backgroundColor = .gray vSep.heightAnchor.constraint(equalToConstant: 2.0).isActive = true stack.addArrangedSubview(vSep) stack.setCustomSpacing(20.0, after: vSep) promptLabel = UILabel() promptLabel.text = "Toggle button images for states:" stack.addArrangedSubview(promptLabel) titles.forEach { t in hs = UIStackView() hs.spacing = 8 hs.alignment = .center promptLabel = UILabel() promptLabel.text = t hs.addArrangedSubview(promptLabel) let v = UIImageView(image: imgs[t]) v.contentMode = .scaleAspectFit v.heightAnchor.constraint(equalTo: v.widthAnchor).isActive = true hs.addArrangedSubview(v) let sw = UISwitch() sw.isOn = true toggles.append(sw) hs.addArrangedSubview(sw) stack.addArrangedSubview(hs) } stack.translatesAutoresizingMaskIntoConstraints = false view.addSubview(stack) let g = view.safeAreaLayoutGuide NSLayoutConstraint.activate([ stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0), stack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0), stack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0), button.heightAnchor.constraint(equalToConstant: 60.0), ]) toggles.forEach { sw in sw.addTarget(self, action: #selector(swTapped(_:)), for: .valueChanged) } button.addTarget(self, action: #selector(btnTapped(_:)), for: .touchUpInside) } @objc func swTapped(_ sender: UISwitch) { guard let idx = toggles.firstIndex(of: sender) else { return } switch idx { case 1: button.setImage(sender.isOn ? imgs[titles[0]] : nil, for: .normal) () case 2: button.setImage(sender.isOn ? imgs[titles[1]] : nil, for: .highlighted) () case 3: button.setImage(sender.isOn ? imgs[titles[2]] : nil, for: .selected) () default: button.isSelected = sender.isOn () } } @objc func btnTapped(_ sender: UIButton) { print("button.isSelected =", sender.isSelected) } }
型看起来像这样:x1c 0d1x的数据运行时,切换.isSelected开关将把button.isSelected设置为true或false。切换按钮图像状态开关将图像设置为图像(如果打开)或将其设置为nil(如果关闭)。或许值得注意的是...当按钮具有:
.isSelected
button.isSelected
true
false
nil
btn.isSelected = true
型
在上面的示例代码中可以看到,将.isSelected切换为On,然后点击按钮。我们不再看到“Highlighted”标题或图像。如果这是你想要的行为,很好!如果不是,你可能需要重新考虑你的方法。
1条答案
按热度按时间mzillmmw1#
Apple的docs:
讨论
在将图像关联到按钮时,至少应始终为正常状态设置一个图像。如果未为其他状态指定图像,则按钮将使用与正常状态关联的图像。如果未为正常状态指定图像,则按钮将使用系统值。
目前尚不清楚的是,呼吁:
字符串
也可以读作:“未指定
.selected
状态的映像"。因此,按钮将使用来自
.normal
的图像。如果您想在将按钮状态设置为
.selected
时删除图像:型
下面是一些示例代码:
型
看起来像这样:
x1c 0d1x的数据
运行时,切换
.isSelected
开关将把button.isSelected
设置为true
或false
。切换按钮图像状态开关将图像设置为图像(如果打开)或将其设置为
nil
(如果关闭)。或许值得注意的是...
当按钮具有:
型
在上面的示例代码中可以看到,将
.isSelected
切换为On,然后点击按钮。我们不再看到“Highlighted”标题或图像。如果这是你想要的行为,很好!如果不是,你可能需要重新考虑你的方法。