以编程方式设置约束,以便视图全屏
Posted
技术标签:
【中文标题】以编程方式设置约束,以便视图全屏【英文标题】:Set constraints programmatically so that view is fullscreen 【发布时间】:2020-06-08 11:57:37 【问题描述】:我在UINavigationController
中添加了loadingComponent
(UIView
),并尝试将约束设置为全屏。问题是loadingComponent
的topAnchor
从navigationBar
的底部开始。
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
【讨论】:
以上是关于以编程方式设置约束,以便视图全屏的主要内容,如果未能解决你的问题,请参考以下文章