【问题标题】:UIView programatic constraints not workingUIView 编程约束不起作用
【发布时间】:2017-07-18 19:48:39
【问题描述】:

作为一个简单的起点。我正在尝试创建一个中间有一个活动指示器的自定义按钮。 点击后 - 它会表明它正在思考

我几乎停留在第 1 步 - 将指示器添加到周围视图的中心。 无论想要约束我尝试它总是出现在左上角。

我错过了什么?

这是我的游乐场代码。

//: Playground - noun: a place where people can play

import PlaygroundSupport
import UIKit

class ConnectButton : UIView {

    fileprivate let activityIndicator: UIActivityIndicatorView = {
        let activityIndicator = UIActivityIndicatorView()

        activityIndicator.color = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        activityIndicator.hidesWhenStopped = true;
        activityIndicator.stopAnimating();
        activityIndicator.activityIndicatorViewStyle = .white;
        return activityIndicator;
    }()


    private func initView() {
        translatesAutoresizingMaskIntoConstraints = true;
        addSubview(activityIndicator);

        NSLayoutConstraint.activate([
            activityIndicator.centerYAnchor.constraint(equalTo: self.centerYAnchor),
            activityIndicator.leftAnchor.constraint(equalTo: self.centerXAnchor)
        ])
    }

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

    override init(frame: CGRect) {
        super.init(frame: frame);
        self.initView();
    }

    public func startAnimating() {
        activityIndicator.startAnimating();
    }

    public func stopAnimating() {
        activityIndicator.stopAnimating();
    }
}

let dimensions = (width:200, height: 50);
let connectButton = ConnectButton(
    frame: CGRect(
        x: dimensions.width / 2,
        y: dimensions.height / 2,
        width: dimensions.width,
        height: dimensions.height
    )
)

connectButton.startAnimating();
connectButton.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1);

PlaygroundPage.current.liveView = connectButton

【问题讨论】:

  • 添加 self.view.layoutIfNeeded() 或 activityIndi​​cator.layoutIfNeeded() 以更新约束更改。但是,由于我没有在 Swift 中编码,我真的不明白 self.centerYAnchor 是什么,我在您的代码中的任何地方都看不到它,self.centerXAnchor 也没有。如果您在 viewDidLoad 方法中更改这些约束,请记住,当您在 viewDidLoad 中时,您的 superView 约束尚未计算,除非您已经为其设置了特定的高度/宽度。
  • 我将 self.layoutIfNeeded() 和 activityIndi​​cator.layoutIfNeeded() 添加到 initView 中,然后最后在 Playground 代码中 - 没有变化
  • 在初始化 subView 后将其添加到您的 superView。
  • 我直接在视图中创建它作为可重用的自定义控件。没有 UIViewController(我正在游乐场中进行原型设计 - 我假设游乐场代码中的最后一个代码会产生类似的效果)。我正在使用 translatesAutoresizingMaskIntoConstraints = true。我可以删除它并将实际的高度和宽度常量放入 - 但具有相同的“不居中”效果。
  • 嗯,你读过下面tomahhs的回答吗?我将添加另一个解决方案,您可以尝试简化事情

标签: ios swift uiview


【解决方案1】:

另一个解决方案:像你已经做的那样,使用你的 superView 中的给定框架创建你的 UIActivityIndi​​cator,然后简单地调用:

activityIndicator.center = self.center

并避免使用NSLayoutConstraints,除非你真的需要它们。

但是,正如我在 cmet 部分中提到的,在调用上述行之前,请确保您的 UIView 布局正确。否则你的结果会完全一样。

【讨论】:

  • 之前玩过这个。问题是对于以后的代码,事情可能并不总是居中,需要灵活处理屏幕尺寸和旋转
  • @MickCrozier 我明白了,如果你真的想避免所有的混乱,我建议你使用情节提要,创建一个 XIB 并将其设置为你的 UIView 子类。从情节提要中添加视图和约束,您将拥有完全的视觉控制。当您想将它添加到您的 superView 时,您只需使用如下一行代码加载它:stackoverflow.com/questions/35659714/…。此外,将所有代码放在 developer.apple.com/reference/objectivec/nsobject/… 中,而不是 initFrame。
【解决方案2】:

您想将translatesAutoresizingMaskIntoConstraints 设置为falseUIActivityIndicatorView。否则,UIKit 将根据在 上设置的调整大小蒙版创建约束,这将与您已添加的蒙版冲突。

fileprivate let activityIndicator: UIActivityIndicatorView = {
    let activityIndicator = UIActivityIndicatorView()

    activityIndicator.color = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    activityIndicator.hidesWhenStopped = true
    activityIndicator.stopAnimating()
    activityIndicator.activityIndicatorViewStyle = .white
    activityIndicator. translatesAutoresizingMaskIntoConstraints = false
    return activityIndicator
}()

【讨论】:

  • 赞成,但您应该在回答中澄清您的意思以及顺便说一句,因为这对于阅读它的人来说并不明显。
  • 好电话。我误读了问题中的代码,尽管 op 在initView 中将它们设置为false。答案已更新:)
  • 啊——砰。而已。谢谢@tomahh
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多