ios - Swift:UIControls 的 UIStackView 与不会触发的选择器方法
问题描述
介绍
我正在创建一个使用自定义视图的应用程序,其中我有一个 UIStackView 来整理 5 个 UIControls。当用户点击其中一个 UIControls 时,下划线将变为动画,在点击的 UIControl 下方滑动。
但是,由于某种原因,这些 UIControls 的方法/选择器不再被调用。我相信这与我将我的 Mac 更新为本周(wk.44)发布的 macOS(和 Xcode)更新有关。(从 swift 4.2 更新到 swift 4.2.1)。在更新之前,此动画和选择器运行良好。但我不确定。我现在完全坚持我做错了什么。
语境
我创建了一个游乐场并尽可能地缩小了所有内容,但问题仍然存在。
我试图在我的
SetupView
班级的全局范围内定义 UIStackView 但它没有改变任何东西。所以我相信这不是stackView或其子视图被释放的问题吗?下面我提供了我的 UIControl 子类和我
SetupView
使用的(UIView 子类)。我已经创建了一个 Playground,因此您可以在 Xcode Playground 中复制粘贴以进行测试。
问题
- 为什么不
goalViewControlTapped(_ sender: SetupViewControl)
调用该方法?
代码
import UIKit
import PlaygroundSupport
class SetupViewControl: UIControl {
let titleLabel : UILabel = {
let lbl = UILabel()
lbl.font = UIFont(name: "Futura", size: 14)
lbl.textColor = .white
lbl.backgroundColor = .clear
lbl.textAlignment = .center
lbl.translatesAutoresizingMaskIntoConstraints = false
return lbl
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupLabel()
layer.cornerRadius = 5
}
fileprivate func setupLabel() {
addSubview(titleLabel)
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5).isActive = true
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var isHighlighted: Bool {
didSet {
UIView.animate(withDuration: 0.12) {
self.backgroundColor = self.isHighlighted ? UIColor.lightGray : UIColor.clear
}
}
}
}
class SetupView: UIView {
let dataModel : [String] = ["2 weeks", "1 month", "2 months", "6 months", "1 year"]
var selectionLineCenterX : NSLayoutConstraint!
let selectionLine = UIView()
let labelZero = SetupViewControl()
let labelOne = SetupViewControl()
let labelTwo = SetupViewControl()
let labelThree = SetupViewControl()
let labelFour = SetupViewControl()
let labelFive = SetupViewControl()
lazy var controlArray = [self.labelZero, self.labelOne, self.labelTwo, self.labelThree, self.labelFour, self.labelFive]
init(frame: CGRect, color: UIColor) {
super.init(frame: frame)
self.backgroundColor = color
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func setupView() {
layer.cornerRadius = 0
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 1
setupLabelText()
setupControlsInStackView()
}
fileprivate func setupLabelText() {
for num in 0...(dataModel.count - 1) {
controlArray[num].titleLabel.text = dataModel[num]
}
}
// let stackView = UIStackView(frame: .zero) I have tried to declare the stackView here but it doesn't fix my issue.
func setupControlsInStackView() {
var stackViewArray = [SetupViewControl]()
for num in 0...(dataModel.count - 1) {
controlArray[num].isUserInteractionEnabled = true
controlArray[num].addTarget(self, action: #selector(goalViewControlTapped(_:)), for: .touchUpInside)
stackViewArray.append(controlArray[num])
}
let stackView = UIStackView(arrangedSubviews: stackViewArray)
stackView.alignment = .fill
stackView.distribution = .fillEqually
stackView.axis = .horizontal
stackView.translatesAutoresizingMaskIntoConstraints = false
addSubview(stackView)
stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8).isActive = true
stackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8).isActive = true
stackView.topAnchor.constraint(equalTo: topAnchor, constant: 15).isActive = true
addSubview(selectionLine)
selectionLine.backgroundColor = .white
selectionLine.translatesAutoresizingMaskIntoConstraints = false
selectionLine.heightAnchor.constraint(equalToConstant: 1).isActive = true
selectionLine.topAnchor.constraint(equalTo: stackView.bottomAnchor).isActive = true
selectionLine.widthAnchor.constraint(equalToConstant: 50).isActive = true
selectionLineCenterX = selectionLine.centerXAnchor.constraint(equalTo: leadingAnchor, constant: -100)
selectionLineCenterX.isActive = true
}
@objc fileprivate func goalViewControlTapped(_ sender: SetupViewControl) {
print("This is not getting printed!!!")
selectionLineCenterX.isActive = false
selectionLineCenterX = selectionLine.centerXAnchor.constraint(equalTo: sender.centerXAnchor)
selectionLineCenterX.isActive = true
UIView.animate(withDuration: 0.25, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.5, options: .curveEaseIn, animations: {
self.layoutIfNeeded()
}, completion: nil)
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let testView = SetupView(frame: .zero, color: UIColor.blue)
view.addSubview(testView)
testView.translatesAutoresizingMaskIntoConstraints = false
testView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
testView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
testView.heightAnchor.constraint(equalToConstant: 100).isActive = true
testView.widthAnchor.constraint(equalToConstant: 365).isActive = true
}
}
// For live view in playground
let vc = ViewController()
vc.preferredContentSize = CGSize(width: 375, height: 812)
PlaygroundPage.current.liveView = vc
感谢您阅读我的问题。
解决方案
当您打开视图调试器时,您的显示是否UIStackView
具有模棱两可的布局?如果是这样,那可能会导致内部视图无法接收到触摸事件。
您可以提供UIStackView
:
x
和y
仅约束
或者
x
, y
,width
和 height
.
在上述情况下,height
缺少约束。
推荐阅读
- django - 错误消息中的 Django Formset 字段标签
- vuejs2 - 使用 vee-validate 进行自定义验证
- parsing - 云雀中earley和lalr解析器的区别?
- java - 如何限制在 tomcat-8 上运行的 JSP 页面的客户端连接数?
- azure - 将虚拟目录映射到 Azure 文件存储中的挂载文件位置
- r - x[, cols] 不等于 x[, ..cols] 和 x[, cols, with=FALSE]
- php - 更改 WooCommerce 订单状态更改而不发送电子邮件通知
- javascript - 2秒后自动调用Javascript代码
- sql-server - 如何在更新查询中使用 STRING_SPLIT()?
- javascript - 使用 JS,如何检测广告拦截器?