以编程方式设置约束,以便视图全屏

Posted

技术标签:

【中文标题】以编程方式设置约束,以便视图全屏【英文标题】: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”视图覆盖导航栏 【参考方案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
    

【讨论】:

以上是关于以编程方式设置约束,以便视图全屏的主要内容,如果未能解决你的问题,请参考以下文章

h5 video切换到横屏全屏

javascript 浏览器全屏全屏

javascript 全屏全屏pantalla completa F11

以编程方式创建全屏 RelativeLayout

切换到横向时,Tableview 将约束更改为全屏

是否可以以编程方式强制 iOS 应用程序在拆分视图/滑动中在 ios9 中全屏显示?