【问题标题】:UIButton in custom UIScrollView class not responding to touches自定义 UIScrollView 类中的 UIButton 不响应触摸
【发布时间】:2018-09-15 04:33:13
【问题描述】:

我有如下视图结构;

-->Custom Scroll View
    -->Container View
       -->View
          -->Button

我的问题是我正在向 UIButton 添加一个目标,但没有调用触摸功能。我尝试在自定义视图类或视图控制器中添加目标。但是,两者都不起作用。

我检查了什么;

  • 我检查了所有视图的 isUserInteractionEnabled 是否都设置为 true 并且所有视图都为 true。
  • 我还检查了按钮是否有框架(有些帖子说 UIButton 可以看到但你不能触摸它,因为它没有框架)。

我可能检查了堆栈溢出中的每个答案,其中大多数都在谈论 isUserInteraction 和层次结构,我认为它们在我的情况下都是正确的。

UIButton not clickable when custom view called

Custom UIView add target not called

我如何创建自定义视图并在其中添加按钮。

class TyreChangeScrollView: UIScrollView {

//E-Mail
let emailTitleLbl = BaseLabel()
let emailBgView = UIView()
let emailLbl = BaseLabel()
public let emailInfoBtn = UIButton()

let contentView: UIView = {
    let v = UIView()
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()

var shouldSetupConstraints = true

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

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

func updateUI(){
    addSubview(contentView)

    emailTitleLbl.translatesAutoresizingMaskIntoConstraints = false
    emailTitleLbl.text =  "E-POSTA ADRESİ"
    emailTitleLbl.textAlignment = .left
    contentView.addSubview(emailTitleLbl)

    emailLbl.translatesAutoresizingMaskIntoConstraints = false
    emailLbl.text =  "hello@hello.com"
    emailLbl.textAlignment = .left
    emailInfoBtn.setImage(UIImage(named: "info"), for: .normal)
    emailInfoBtn.isUserInteractionEnabled = true
    emailBgView.backgroundColor = Color.Common.fieldBg
    emailBgView.addSubview(emailLbl)
    emailBgView.addSubview(emailInfoBtn)
    contentView.addSubview(emailBgView)
}
override func updateConstraints() {
    if(shouldSetupConstraints) {
        // AutoLayout constraints
        contentView.translatesAutoresizingMaskIntoConstraints = false
        // constrain the scroll view to 8-pts on each side
        contentView.anchor(self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
        contentView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1.0).isActive = true

        emailTitleLbl.anchor(phoneLbl.bottomAnchor, left: contentView.leftAnchor, bottom: nil, right: contentView.rightAnchor, topConstant: 10, leftConstant: 20, bottomConstant: 0, rightConstant: 16, widthConstant: 0, heightConstant: 0)
        emailLbl.anchor(emailBgView.topAnchor, left: emailBgView.leftAnchor, bottom: emailBgView.bottomAnchor, right: nil, topConstant: 0, leftConstant: 15, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
        emailInfoBtn.anchor(emailBgView.topAnchor, left: nil, bottom: emailBgView.bottomAnchor, right: emailBgView.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 10, widthConstant: 0, heightConstant: 0)
        emailBgView.anchor(emailTitleLbl.bottomAnchor, left: contentView.leftAnchor, bottom: nil, right: contentView.rightAnchor, topConstant: 10, leftConstant: 20, bottomConstant: 0, rightConstant: 16, widthConstant: 0, heightConstant: 50)

        shouldSetupConstraints = false
    }
    super.updateConstraints()
}
}

我如何声明自定义类并将目标添加到 UIButton。

class TyreChangeViewController: BaseViewController{

let scrollView = TyreChangeScrollView()

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    designUI()
    scrollView.emailInfoBtn.addTarget(self, action: #selector(emailBtnTapped(_:)), for: UIControlEvents.touchUpInside)
    scrollView.phoneInfoBtn.addTarget(self, action: #selector(phoneBtnTapped(_:)), for: UIControlEvents.touchUpInside)

}
override func viewWillAppear(_ animated: Bool) {

    scrollView.anchor(topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: bottomLayoutGuide.topAnchor, right: view.rightAnchor, topConstant: 10, leftConstant: 10, bottomConstant: 10, rightConstant: 10, widthConstant: 0, heightConstant: 0)
}
func designUI(){

    view.backgroundColor = Color.Common.screenBgColor
    scrollView.backgroundColor = Color.Common.screenBgWhite
    view.addSubview(scrollView)

}
@objc func emailBtnTapped(_ sender: UIButton){
    print("hello")
}}

编辑:如果我向内容视图添加高度约束,按钮可以工作,但现在它不可滚动。

contentView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1.0).isActive = true

【问题讨论】:

  • view-hierchy 告诉你关于滚动视图大小的什么信息?
  • 它说“TyreChangeScrollView 的可滚动内容大小不明确”,但在调试视图层次结构中高度为 534
  • 我的猜测是高度常数 0 与您的底部和高度约束冲突。使滚动视图转到边缘,您的 containerView 将高度和宽度设置为 UIScreen.main.bounds.height / width 并在 scrollView 中居中 x,y
  • 我编辑我的问题。你能检查一下吗?
  • 我认为你的滚动视图是 0 宽度,所以也要设置你的 contentView 宽度

标签: ios swift uiview uibutton


【解决方案1】:

添加约束后刷新布局是必须的

override func viewWillAppear(_ animated: Bool) {

    scrollView.anchor(topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: bottomLayoutGuide.topAnchor, right: view.rightAnchor, topConstant: 10, leftConstant: 10, bottomConstant: 10, rightConstant: 10, widthConstant: 0, heightConstant: 0)

    self.view.layoutIfNeeded()
 }

【讨论】:

  • 我在 emailView 下方添加了一个大标签来检查它是否可滚动。我将标签置于 self.contenview.belowanchor 的约束之下,但使其不可滚动。
  • 在 viewWillAppear 中添加 self.view.layoutIfNeeded()
  • 你是男人!谢谢 :) 它奏效了。你能编辑你的答案,我会打勾作为工作溶胶。
  • 我能问更多吗?在大多数帖子中,他们说我需要同时具有相等的宽度和高度,但我只是在我的代码中分配宽度,因为当我使高度约束与滚动视图相等时,它不会滚动。会有问题吗?
  • scrollView 的 contentView 必须从 scrollView 外部获取它的宽度到与任何外部组件相关的静态宽度或宽度,但是(contentView 的)高度必须通过正确连接所有内部项目来动态计算从上到下 contentView ,所以自动布局可以计算出它的适当高度,并且滚动视图可以相应地滚动
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多