设置 button.frame.origin 不会快速更改 scrollView 中的位置

Posted

技术标签:

【中文标题】设置 button.frame.origin 不会快速更改 scrollView 中的位置【英文标题】:Setting button.frame.origin does not change the location in scrollView in swift 【发布时间】:2020-02-20 17:59:18 【问题描述】:

我正在快速以编程方式在垂直 ScrollView 中添加一些按钮。对于每个按钮,我计算同一行中的房间。如果房间足够,则在上一个按钮之后添加该按钮,否则将添加到新行。我尝试使用

设置每个按钮的位置
topButtons[j].frame.origin.x = currentOriginX
topButtons[j].frame.origin.y = currentOriginY

currentOriginX 和 currentOriginY 在每次迭代中都会发生变化。但是,按钮仍然出现在滚动视图的左上角,因此彼此重叠。我该如何解决这个问题? (另外我想保持按钮宽度与其文本相同,所以我没有设置按钮的宽度。)

我的代码附在下面。

    @IBOutlet weak var topScrollView: UIScrollView!
    var topButtons = [UIButtons()]
    func displayTopItems() 

        let scrollViewWidth = topScrollView.frame.size.width
        let buttonHeight = CGFloat(40)
        var currentOriginX = topScrollView.frame.origin.x
        var currentOriginY = topScrollView.frame.origin.y
        self.topScrollView.automaticallyAdjustsScrollIndicatorInsets = false
        self.topScrollView.isScrollEnabled = true
        self.topScrollView.isUserInteractionEnabled = true
        self.topScrollView.translatesAutoresizingMaskIntoConstraints = false

        for j in 0..<self.itemsClass.toBuyItems.count 

            topButtons.append(UIButton(type: UIButton.ButtonType.system))
            topButtons[j].setTitle(self.itemsClass.toBuyItems[j], for: UIControl.State.normal)

            let buttonWidth = topButtons[j].frame.size.width
            if j > 0 
                let lastButtonLeft = topButtons[j-1].frame.origin.x
                let lastButtonWidth = topButtons[j-1].frame.size.width
                let sameRow = lastButtonLeft + lastButtonWidth + buttonWidth + 50 < scrollViewWidth
                if sameRow 
                    currentOriginX += lastButtonWidth + 30
                
                else 
                    currentOriginX = 0
                    currentOriginY += buttonSize.height + 20
                
            
//            self.topScrollView.contentOffset.x = currentOriginX
//            self.topScrollView.contentOffset.y = currentOriginY
            topButtons[j].frame.origin.x = currentOriginX
            topButtons[j].frame.origin.y = currentOriginY
            topButtons[j].setTitleColor(UIColor.white, for: UIControl.State.normal)
            topButtons[j].backgroundColor = UIColor.black
            topButtons[j].translatesAutoresizingMaskIntoConstraints = false
            topButtons[j].heightAnchor.constraint(equalToConstant: buttonSize.height).isActive = true
            topButtons[j].layer.borderColor = UIColor.red.cgColor
            topButtons[j].layer.cornerRadius = 10.0
            topButtons[j].addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
            topButtons[j].tag = j
            self.topScrollView.addSubview(topButtons[j])
        
    

【问题讨论】:

var currentOriginX = topScrollView.frame.origin.x 应该是var currentOriginX = topScrollView.bounds.origin.x,不是吗? currentOriginY 也一样。 更改无效... 您正在混合显式框架和自动布局/约束,这通常会导致问题。你有这条线:let buttonSize: CGSize = CGSize(width: 200, height: 40) ...这是否意味着你希望所有按钮都是200 x 40?还是您希望它们高 40 磅但宽度适合标题? 【参考方案1】:

按钮的位置需要在添加到视图后通过指定约束来设置。

    topButtons[j].setTitleColor(UIColor.white, for: UIControl.State.normal)
    topButtons[j].backgroundColor = UIColor.black
    topButtons[j].translatesAutoresizingMaskIntoConstraints = false
    topButtons[j].heightAnchor.constraint(equalToConstant: buttonSize.height).isActive = true
    topButtons[j].layer.borderColor = UIColor.red.cgColor
    topButtons[j].layer.cornerRadius = 10.0
    topButtons[j].addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
    topButtons[j].tag = j
    self.topScrollView.addSubview(topButtons[j])
    // do this after adding buttons to view
    topButtons[j].topAnchor.constraint(equalTo: topScrollView.topAnchor, constant: currentOriginY).isActive = true
    topButtons[j].leadingAnchor.constraint(equalTo: topScrollView.leadingAnchor, constant: currentOriginX).isActive = true

【讨论】:

以上是关于设置 button.frame.origin 不会快速更改 scrollView 中的位置的主要内容,如果未能解决你的问题,请参考以下文章

如何用动画改变按钮的位置

以编程方式控制滚动视图——Objective-c

不会设置依赖属性

cookie 不会取消设置

SLComposeViewController 不会为 SLServiceTypeFacebook 设置 initialText

向 app.config 添加了新的应用程序设置,但 MSI 不会安装它(不会覆盖)