【问题标题】:Set constraints programmatically so that view is fullscreen以编程方式设置约束,以便视图全屏
【发布时间】:2020-06-08 11:57:37
【问题描述】:

我在UINavigationController 中添加了loadingComponent (UIView),并尝试将约束设置为全屏。问题是loadingComponenttopAnchornavigationBar的底部开始。

    private let loadingComponent: LoadingComponent = {

        let loadingComponent = LoadingComponent.usingAutoLayout()
        loadingComponent.translatesAutoresizingMaskIntoConstraints = false
        loadingComponent.render(with: .configure(.init(backgroundColor: ColorName.white.color,
                                                       styleText: StyledText(text: L10n.Submit.Upload.inProgress,
                                                                             style: StyleSheet.Label.boldDark19),
                                                       alpha: 1.0)))

        return loadingComponent
    }()

    private func defineSubviewsConstraints() {

        NSLayoutConstraint.activate([

            self.loadingComponent.topAnchor.constraint(equalTo: self.topAnchor),
            self.loadingComponent.bottomAnchor.constraint(equalTo: self.bottomAnchor),
            self.loadingComponent.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            self.loadingComponent.trailingAnchor.constraint(equalTo: self.trailingAnchor)
        ])
    }

【问题讨论】:

  • 你当前的代码怎么不工作?
  • 您是否尝试过更改子视图顺序?即 self.view.bringSubviewToFront(subview)
  • @Sweeper 我可以看到 loadingComponent 但它是从导航栏的底部开始的,所以不是全屏
  • 其实你的代码中self是什么? UIView 子类?这不是UIViewController 是吗?
  • @bruno - 您是否尝试用“loadingComponent”视图覆盖导航栏

标签: ios swift autolayout constraints


【解决方案1】:

更新:更新问题后尝试不使用static 方法,而是在init 方法中执行您在usingAutoLayout 中所做的操作,并像这样初始化loadingComponent

private let loadingComponent: LoadingComponent = {
    let loadingComponent = LoadingComponent()
    loadingComponent.translatesAutoresizingMaskIntoConstraints = false
    loadingComponent.render(with: .configure(.init(backgroundColor: ColorName.white.color,
                                                   styleText: StyledText(text: L10n.Submit.Upload.inProgress,
                                                                         style: StyleSheet.Label.boldDark19),
                                                   alpha: 1.0)))
    return loadingComponent
}()

在向视图添加约束之前,您需要将translatesAutoresizingMaskIntoConstraints 属性设置为false

loadingComponent.translatesAutoresizingMaskIntoConstraints = false

【讨论】:

  • 你究竟为什么要调用静态成员来初始化?你的代码是不是看起来太复杂了,可读性太低了。
  • 因为它是用于每个 UI 的扩展中的方法,但我更新了代码
  • 好的,但为什么是静态的?
  • 我去掉了静电
  • 您现在面临的问题是什么?
【解决方案2】:

我建议使用这个超级方便的UIView 扩展来进行约束。 然后,您只需拨打loadingComponent.layoutAttachAll() 即可。

extension UIView {
    /// attaches all sides of the receiver to its parent view
    func coverWholeSuperview(margin: CGFloat = 0.0) {
        let view = superview
        layoutAttachTop(to: view, margin: margin)
        layoutAttachBottom(to: view, margin: margin)
        layoutAttachLeading(to: view, margin: margin)
        layoutAttachTrailing(to: view, margin: margin)
    }

    /// attaches the top of the current view to the given view's top if it's a superview of the current view
    /// or to it's bottom if it's not (assuming this is then a sibling view).
    @discardableResult
    func layoutAttachTop(to: UIView? = nil, margin: CGFloat = 0.0) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = view == superview
        let constraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal,
                                            toItem: view, attribute: isSuperview ? .top : .bottom, multiplier: 1.0,
                                            constant: margin)
        superview?.addConstraint(constraint)

        return constraint
    }

    /// attaches the bottom of the current view to the given view
    @discardableResult
    func layoutAttachBottom(to: UIView? = nil, margin: CGFloat = 0.0, priority: UILayoutPriority? = nil) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = (view == superview) || false
        let constraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal,
                                            toItem: view, attribute: isSuperview ? .bottom : .top, multiplier: 1.0,
                                            constant: -margin)
        if let priority = priority {
            constraint.priority = priority
        }
        superview?.addConstraint(constraint)

        return constraint
    }
    /// attaches the leading edge of the current view to the given view
    @discardableResult
    func layoutAttachLeading(to: UIView? = nil, margin: CGFloat = 0.0) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = (view == superview) || false
        let constraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal,
                                            toItem: view, attribute: isSuperview ? .leading : .trailing, multiplier: 1.0,
                                            constant: margin)
        superview?.addConstraint(constraint)

        return constraint
    }

    /// attaches the trailing edge of the current view to the given view
    @discardableResult
    func layoutAttachTrailing(to: UIView? = nil, margin: CGFloat = 0.0, priority: UILayoutPriority? = nil) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = (view == superview) || false
        let constraint = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal,
                                            toItem: view, attribute: isSuperview ? .trailing : .leading, multiplier: 1.0,
                                            constant: -margin)
        if let priority = priority {
            constraint.priority = priority
        }
        superview?.addConstraint(constraint)

        return constraint
    }

    // for anchoring View
    struct AnchoredConstraints {
        var top, leading, bottom, trailing, width, height, centerX, centerY: NSLayoutConstraint?
    }

    @discardableResult
    func constraints(top: NSLayoutYAxisAnchor? = nil, leading: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil,
                trailing: NSLayoutXAxisAnchor? = nil, padding: UIEdgeInsets = .zero, size: CGSize = .zero,
                centerX: NSLayoutXAxisAnchor? = nil, centerY: NSLayoutYAxisAnchor? = nil,
                centerXOffset: CGFloat = 0, centerYOffset: CGFloat = 0) -> 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)
        }

        if let centerX = centerX {
            anchoredConstraints.centerX = centerXAnchor.constraint(equalTo: centerX, constant: centerXOffset)
        }

        if let centerY = centerY {
            anchoredConstraints.centerY = centerYAnchor.constraint(equalTo: centerY, constant: centerYOffset)
        }

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

        return anchoredConstraints
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多