宽度和高度等于它的超级查看使用自动布局编程?
我一直在寻找networking中的很多片段,我仍然无法find我的问题的答案。 我的问题是我有一个scrollView(SV),我想要在scrollView(SV)内以编程方式添加一个button,它的超级视图的scrollView(SV)的宽度和高度相同,这样当用户旋转设备button时将会有相同的框架scrollView(SV)的。 如何做NSLayout / NSLayoutConstraint? 谢谢
如果有人正在寻找一个Swift解决scheme – 我会创build一个UIView
的Swift 扩展,这将帮助你每次你想绑定一个子视图框架的超级界限:
Swift 2:
extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }
Swift 3:
extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }
然后简单地这样调用它 :
// after adding as a subview, eg `view.addSubview(subview)` subview.bindFrameToSuperviewBounds()
我不知道这是否是最有效的方法,但它的工作原理..
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.translatesAutoresizingMaskIntoConstraints = NO; // initialize [coverForScrolView addSubview:button]; NSLayoutConstraint *width =[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:0 toItem:coverForScrolView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; NSLayoutConstraint *height =[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeHeight relatedBy:0 toItem:coverForScrolView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:coverForScrolView attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.f]; NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:coverForScrolView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.f]; [coverForScrolView addConstraint:width]; [coverForScrolView addConstraint:height]; [coverForScrolView addConstraint:top]; [coverForScrolView addConstraint:leading];
这个链接可以帮助你,按照说明: http : //www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
编辑:
使用下面的代码片段,其中subview是你的subivew。
[subview setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview)]];
Swift 3:
import UIKit extension UIView { func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }
UIView的addConstraint
和removeConstraint
方法将被弃用,所以值得使用'约束创build方便':
view.topAnchor.constraint(equalTo: superView.topAnchor, constant: 0).isActive = true view.bottomAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0).isActive = true view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0).isActive = true view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0).isActive = true
作为@ Dschee的解决scheme的后续,这里是swift 3.0语法:(请注意:这不是我的解决scheme ,我刚刚修复了Swift 3.0)
extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) }
方法#1:通过UIView扩展
Swift 3中的一个更具function性的方法是使用前提条件而不是print
(在控制台中可以很容易消失)。 这一个将报告程序员错误作为失败的版本。
将此扩展添加到您的项目中:
extension UIView { /// Adds constraints to the superview so that this view has same size and position. /// Note: This fails the build if the `superview` is `nil` – add it as a subview before calling this. func bindEdgesToSuperview() { guard let superview = superview else { preconditionFailure("`superview` was nil – call `addSubview(view: UIView)` before calling `bindEdgesToSuperview()` to fix this.") } translatesAutoresizingMaskIntoConstraints = false ["H:|-0-[subview]-0-|", "V:|-0-[subview]-0-|"].forEach { visualFormat in superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: visualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } } }
现在简单地这样调用它 :
// after adding as a subview, eg `view.addSubview(subview)` subview.bindEdgesToSuperview()
请注意,上面的方法已经集成到我的HandyUIKit框架中,它也添加了一些更方便的UI助手到您的项目。
方法#2:使用框架
如果您在项目中使用了编程约束 ,那么我build议您签出SnapKit 。 这使得使用约束更容易 , 更不容易出错 。
按照文档中的安装说明将SnapKit包含到您的项目中。 然后将其导入到Swift文件的顶部:
import SnapKit
现在你可以用这个来达到同样的目的:
subview.snp.makeConstraints { make in make.edges.equalToSuperview() }
作为补充答案,对于那些不反对join第三方库的人来说, PureLayout库提供了一个方法来做到这一点。 一旦库被安装,它就像
myView.autoPinEdgesToSuperviewEdges()
还有其他的库可以提供类似的function,以及根据口味,例如。 砌体 , 制图 。
@MadNik和@Dschee解决scheme使用目标C和类别:
#import "UIView+UIView.h" @implementation UIView (UIView) - (void) bindFrameToSuperviewBounds{ UIView *superView = self.superview; if (superView == nil){ NSLog(@"Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this."); return; } UIView *subview = self; [superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview) ]]; [superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview) ]]; } @end