如何以编程方式在swift5中居中子视图

cotxawn7  于 2023-03-16  发布在  Swift
关注(0)|答案(2)|浏览(106)

我正在尝试使用中心子视图。但是它似乎不符合预期。我该如何修复它?
这是我的密码

private lazy var uploadButton: UIButton = {
        let button = UIButton()
        let innerView = UIView(frame: CGRect(x: 0, y: 0, width: 136, height: 63))
        innerView.backgroundColor = .cyan
        innerView.center = CGPoint(x: button.frame.size.width/2, y: button.frame.size.height/2)
        button.addSubview(innerView)
        button.layer.cornerRadius = 30
        button.backgroundColor = .white
        button.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        button.layer.shadowOpacity = 1
        button.layer.shadowOffset = CGSize.zero
        button.layer.shadowRadius = 6
        return button
    }()
view.addSubview(uploadButton)
uploadButton.translatesAutoresizingMaskIntoConstraints = false
// ...
uploadButton.bottomAnchor.constraint(equalTo: nextButton.topAnchor, constant: -69),
            uploadButton.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 38),
            uploadButton.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: -38),
            uploadButton.heightAnchor.constraint(equalToConstant: 171)
// all active

h79rfbju

h79rfbju1#

iOS中提供了不同的布局系统
1.自动布局
1.基于框架的布局
1.堆栈视图
1.快速用户界面
现在,为什么代码片段中会出现这种不一致?
上面的代码片段同时使用了Auto LayoutFrame-based Layout,这几乎无法给予您所需的布局或一致的维护方式。
我们来看一个案例。

  • uploadButton基于autolayout
  • innerView基于frame-based布局。
  • 自动布局将动态计算uploadButton的视图大小,因此当您想使用button.frame.size设置innerView中心时,它不会工作,因为此时宽度和高度为零,并将在约束激活后计算。
  • 如果uploadButton只有frame-based布局,则与button.frame.size相关的计算将是有意义的。
    顶级域名注册商

坚持只使用一个布局系统,以保持一致性和直观性,因为混合使用多个系统可能会导致混乱和维护问题。

代码

下面是一个基于auto layout的工作视图。

private lazy var innerView: UIView = {
    let innerView = UIView()
    innerView.translatesAutoresizingMaskIntoConstraints = false
    innerView.backgroundColor = .cyan
    return innerView
}()

private lazy var uploadButton: UIButton = {
    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.backgroundColor = .white
    return button
}()

....
....

// then in viewDidLoad() where you structure view elements
view.addSubview(uploadButton)
uploadButton.addSubview(innerView)

// Try replacing this constraint activation part with any utility extension 
// or storyboard or available library with less code 

let uploadButtonConstraints = [
    uploadButton.leftAnchor.constraint(equalTo: view.leftAnchor),
    uploadButton.rightAnchor.constraint(equalTo: view.rightAnchor),
    uploadButton.topAnchor.constraint(equalTo: view.topAnchor),
    uploadButton.bottomAnchor.constraint(equalTo: view.bottomAnchor)
]
NSLayoutConstraint.activate(uploadButtonConstraints)

let innerViewConstraints = [
    innerView.heightAnchor.constraint(equalToConstant: 63), // hardcoding is bad
    innerView.widthAnchor.constraint(equalToConstant: 136),
    innerView.centerXAnchor.constraint(equalTo: uploadButton.centerXAnchor),
    innerView.centerYAnchor.constraint(equalTo: uploadButton.centerYAnchor)
]
NSLayoutConstraint.activate(innerViewConstraints)
....

结果

"离题“
在为一种语言或平台的开发者设计API时,最好是提供一种单一的方法来完成一项任务,这样可以简化API,减少混淆,例如Go语言设计的指导原则就说明了这一点。
然而,随着语言或平台的发展,它会经历不同的开发阶段,例如iOS应用布局从基于框架到自动布局再到SwiftUI的过渡。为了保持向后兼容性,之前的API也保持可用,这导致开发人员面临多种方法来实现相同的目标或视图,当这些方法混合时会导致混乱。

cdmah0mi

cdmah0mi2#

innerView.center = CGPoint(x:按钮.框架.尺寸.宽度/2,y:按钮.框架.大小.高度/2)按钮.添加子视图(innerView)
我认为您的代码失败是因为在您设置center属性时innerView没有超级视图。

  • 中心点在其超级视图的坐标系中以点为单位指定。设置此属性将相应地更新frame属性中矩形的原点。*

你 * 想要 * 的是设置innerViewbutton中的位置。相应地,你应该先添加innerView作为button的子视图,* 然后 * 设置它的center。所以,交换这两行应该可以解决你的问题。

相关问题