我正在使用单选按钮视图,并已在https://github.com/paulicelli/RadioButton上的github上传了一个测试项目
这基本上是UIStackView的子类,具有IBInspectable数量的按钮来创建一些单选按钮。
在设备上工作,但是当我打开Interface Builder时,我总是看到按钮错位,直到我改变按钮数或间距。您可以在view1中看到问题,然后在view2中找到正确的视图。
问题: 如何在打开按钮时告诉“界面”构建器正确定位按钮?
这是代码:
import UIKit
// ROUNDBUTTON
final class RoundButton: UIButton {
var borderWidth: CGFloat = 2.0
var primaryColor: UIColor = UIColor.blue
var primaryColorWithAlpha: UIColor {
return primaryColor.withAlphaComponent(0.25)
}
override public var buttonType: UIButtonType {
return .custom
}
override public func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = bounds.size.width * 0.5
self.clipsToBounds = true
setupColors()
}
func setupColors() {
switch self.state {
case UIControlState.normal:
super.backgroundColor = .white
self.setTitleColor(primaryColor, for: state)
self.layer.borderColor = primaryColor.cgColor
self.layer.borderWidth = borderWidth
default:
super.backgroundColor = primaryColorWithAlpha
self.setTitleColor(.white, for: state)
}
}
}
// END OF ROUNDBUTTON
// PROTOCOL
@objc protocol RadioButtonsViewDelegate {
@objc optional func didSelectButton(_ aButton: RoundButton?)
}
// END OF PROTOCOL
// RADIOBUTTONSVIEW
@IBDesignable
class RadioButtonsView: UIStackView {
var shouldLetDeselect = true
var buttons = [RoundButton]()
weak var delegate : RadioButtonsViewDelegate? = nil
private(set) weak var currentSelectedButton: RoundButton? = nil
@IBInspectable
var number: Int = 2 {
didSet {
number = max(number, 2)
setupButtons()
}
}
func setupButtons() {
if !buttons.isEmpty {
buttons.forEach { self.removeArrangedSubview($0) }
buttons.removeAll()
}
for i in 0..<self.number {
let button = RoundButton()
button.setTitle("\(i)", for: .normal)
button.addTarget(self, action: #selector(pressed(_:)),
for: UIControlEvents.touchUpInside)
buttons.append(button)
}
}
func pressed(_ sender: RoundButton) {
if (sender.isSelected) {
if shouldLetDeselect {
sender.isSelected = false
currentSelectedButton = nil
}
}else {
buttons.forEach { $0.isSelected = false }
sender.isSelected = true
currentSelectedButton = sender
}
delegate?.didSelectButton?(currentSelectedButton)
}
override init(frame: CGRect) {
super.init(frame: frame)
setupButtons()
}
required init(coder: NSCoder) {
super.init(coder: coder)
setupButtons()
}
override var intrinsicContentSize: CGSize {
return CGSize(width: self.bounds.width,
height: UIViewNoIntrinsicMetric)
}
override func layoutSubviews() {
self.translatesAutoresizingMaskIntoConstraints = false
buttons.forEach { self.addArrangedSubview($0) }
let constraints: [NSLayoutConstraint] = {
var constraints = [NSLayoutConstraint]()
constraints.append(NSLayoutConstraint(item: buttons[0],
attribute: NSLayoutAttribute.width,
relatedBy: NSLayoutRelation.equal,
toItem: self,
attribute: NSLayoutAttribute.height,
multiplier: 1,
constant: 0)
)
for i in 1..<buttons.count {
constraints.append(NSLayoutConstraint(item: buttons[i],
attribute: NSLayoutAttribute.width,
relatedBy: NSLayoutRelation.equal,
toItem: buttons[i - 1],
attribute: NSLayoutAttribute.width,
multiplier: 1,
constant: 0)
)
}
return constraints
}()
self.addConstraints(constraints)
}
}
// END OF RADIOBUTTONSVIEW
修改 根据@dfd的要求,我也尝试过:
@IBInspectable
var number: Int {
get {
setupButtons()
return self.number
}
set {
self.number = max(newValue, 2)
setupButtons()
}
}
我在加载Interface Builder时遇到了2个错误: