gpt4 book ai didi

swift - 在 UIViewController 中添加为 subview 时,自定义 UIView 不响应

转载 作者:行者123 更新时间:2023-11-28 07:33:17 25 4
gpt4 key购买 nike

在那里,我试图将 View 代码与我的 UIViewController 分开,显示部分很好,但不会对用户交互有任何响应。

例如,我有我的 LoginViewController

class LoginViewController: UIViewController,UITextFieldDelegate {

let loginView = LoginView(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(loginView)
loginView.centerInSuperview()//extension to center layouts
loginView.loginButton.addTarget(self, action: #selector(loginPressed(sender:)), for: .touchUpInside)
}

@objc func loginPressed(sender:UIButton){
print("login")
}
}

登录 View 类

class LoginView: UIView {
fileprivate let containerWidth:CGFloat = 250
fileprivate let contentWidth:CGFloat = 240
let containerView:UIView={
let v = UIView()
v.backgroundColor = .white
v.layer.cornerRadius = 8
return v
}()
let passkeyInput:UITextField = {
let tf = UITextField(frame: .zero)
tf.placeholder = "PASSKEY"
tf.textAlignment = .center
tf.anchor( size: CGSize(width: 240, height: 0))
tf.isSecureTextEntry = true
return tf
}()
let loginButton:UIButton={
let button = UIButton()
button.backgroundColor = .red
button.setTitle("LOGIN", for: .normal)
button.anchor( size: CGSize(width: 240, height: 0))
button.layer.cornerRadius = 8
return button
}()
func setupView() {
let stackView = UIStackView(arrangedSubviews: [passkeyInput,loginButton])
stackView.alignment = .center
stackView.distribution = .equalSpacing
stackView.axis = .vertical
stackView.spacing = 20
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5)
addSubview(containerView)
containerView.addSubview(stackView)
containerView.anchor(size: CGSize(width: containerWidth, height: 0))//extension to layout
stackView.fillSuperview()//extension to layout
containerView.centerInSuperview()//extension to layout
}

override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
}

我希望在单击登录按钮时看到“登录”,但由于某种原因,这并没有发生。

我尝试了一些不同的事情:

因此,如果我将所有 View 代码(LoginView 中的代码)放在 UIViewController 中,我可以毫无问题地看到预期结果,但这没有捕获要点——尝试将 View 和 View Controller 分开

如果我在 ViewController 中更改代码,从添加为 subview

view.addSubview(loginView)

替换现有的默认 View ,

view = loginView

它适用于这种情况,但我并不总是想要替换 View ,有时(大多数时候)需要添加 subview

我试图在这里搜索类似的问题,但没有成功,请大家帮忙指出我哪里做错了。

提前致谢。

更新:这是我使用的布局扩展,仍然没有弄清楚是什么导致了这个问题。

struct AnchoredConstraints {
var top, leading, bottom, trailing, width, height: NSLayoutConstraint?
}

extension UIView {

@discardableResult
func anchor(top: NSLayoutYAxisAnchor? = nil, leading: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, trailing: NSLayoutXAxisAnchor? = nil, padding: UIEdgeInsets = .zero, size: CGSize = .zero) -> AnchoredConstraints {

translatesAutoresizingMaskIntoConstraints = false
var anchoredConstraints = AnchoredConstraints()

if let top = top {
anchoredConstraints.top = topAnchor.constraint(equalTo: top, constant: padding.top)
}

if let leading = leading {
anchoredConstraints.leading = leadingAnchor.constraint(equalTo: leading, constant: padding.left)
}

if let bottom = bottom {
anchoredConstraints.bottom = bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom)
}

if let trailing = trailing {
anchoredConstraints.trailing = trailingAnchor.constraint(equalTo: trailing, constant: -padding.right)
}

if size.width != 0 {
anchoredConstraints.width = widthAnchor.constraint(equalToConstant: size.width)
}

if size.height != 0 {
anchoredConstraints.height = heightAnchor.constraint(equalToConstant: size.height)
}

[anchoredConstraints.top, anchoredConstraints.leading, anchoredConstraints.bottom, anchoredConstraints.trailing, anchoredConstraints.width, anchoredConstraints.height].forEach{ $0?.isActive = true }

return anchoredConstraints
}

func fillSuperview(padding: UIEdgeInsets = .zero) {
translatesAutoresizingMaskIntoConstraints = false
if let superviewTopAnchor = superview?.topAnchor {
topAnchor.constraint(equalTo: superviewTopAnchor, constant: padding.top).isActive = true
}

if let superviewBottomAnchor = superview?.bottomAnchor {
bottomAnchor.constraint(equalTo: superviewBottomAnchor, constant: -padding.bottom).isActive = true
}

if let superviewLeadingAnchor = superview?.leadingAnchor {
leadingAnchor.constraint(equalTo: superviewLeadingAnchor, constant: padding.left).isActive = true
}

if let superviewTrailingAnchor = superview?.trailingAnchor {
trailingAnchor.constraint(equalTo: superviewTrailingAnchor, constant: -padding.right).isActive = true
}
}

func centerInSuperview(size: CGSize = .zero) {
translatesAutoresizingMaskIntoConstraints = false
if let superviewCenterXAnchor = superview?.centerXAnchor {
centerXAnchor.constraint(equalTo: superviewCenterXAnchor).isActive = true
}

if let superviewCenterYAnchor = superview?.centerYAnchor {
centerYAnchor.constraint(equalTo: superviewCenterYAnchor).isActive = true
}

if size.width != 0 {
widthAnchor.constraint(equalToConstant: size.width).isActive = true
}

if size.height != 0 {
heightAnchor.constraint(equalToConstant: size.height).isActive = true
}
}

}

最佳答案

该按钮不会触发触摸事件,因为未设置 loginView 的框架。您只需使用 loginView.centerInSuperview() 定义它的位置。

LoginViewControllerviewDidLoad() 方法中添加以下代码,它应该可以工作:

loginView.fillSuperview()

(或其他框架定义)

当您使用 view = loginView 时,frame 设置在别处,这就是它起作用的原因。

关于swift - 在 UIViewController 中添加为 subview 时,自定义 UIView 不响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54011801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com