ネットでたくさんのスニペットを探していましたが、まだ問題の答えが見つかりません。私の質問は、scrollView(SV)があり、scrollView(SV)内に、スクロールビュー(SV)であるスーパービューと同じ幅と高さのボタンをプログラムで追加して、ユーザーが回転したときにデバイスボタンが同じフレームになるようにしたいということです。 scrollView(SV)の。NSLayout / NSLayoutConstraintを行う方法は?ありがとう
回答:
誰かがSwiftソリューションを探している場合–サブビューフレームをそのスーパービュー境界にバインドするたびに役立つSwift拡張機能をUIView
作成します。
スウィフト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]))
}
}
スウィフト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]))
}
}
Swift 4.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
self.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0).isActive = true
self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0).isActive = true
self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0).isActive = true
self.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 0).isActive = true
}
}
次に、単にこのように呼び出します:
// after adding as a subview, e.g. `view.addSubview(subview)`
subview.bindFrameToSuperviewBounds()
constant: 0
パーツを外せば少し短くすることもできます。
これが最も効率的な方法かどうかはわかりませんが、機能します。
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];
NSLayoutConstraint.activateConstraints([width, height, top, leading])
[coverForScrolView addConstraints:@[width, height, top, leading]];
このリンクはあなたを助けることができます、指示に従ってください:http: //www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
編集:
次のコードスニペットを使用します。ここで、サブビューはサブビューです。
[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)]];
V:|[subview]|
なりますH:|[subview]|
addConstraint
そして、removeConstraint
UIViewのための方法は、「制約の作成便利」を使用することの価値があるので、廃止される予定です。
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
constant: 0
パーツを外せば少し短くすることもできます。
ここのより機能的にアプローチスイフト3+との前提条件の代わりに、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, e.g. `view.addSubview(subview)`
subview.bindEdgesToSuperview()
上記のメソッドはすでに私のHandyUIKitフレームワークに統合されており、プロジェクトにさらに便利なUIヘルパーが追加されていることに注意してください。
あなたがいる場合、プログラム制約でたくさんの仕事、プロジェクト内の私がチェックアウトすることをお勧めいたしますSnapKitを。これにより、制約の操作がはるかに簡単になり、エラーが発生しにくくなります。
ドキュメントのインストール手順に従って、SnapKitをプロジェクトに含めます。次に、Swiftファイルの先頭にインポートします。
import SnapKit
今、あなたはこれだけで同じことを達成することができます:
subview.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
スウィフト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]))
}
}
Swift 4の使用NSLayoutConstraint
:
footerBoardImageView.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.width, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.height, multiplier: 1, constant: 0)
superview.addConstraints([widthConstraint, heightConstraint])
補足的な答えとして、そしてサードパーティのライブラリを含めることに反対しない人のための答えとして、PureLayoutライブラリはまさにこれを行う方法を提供します。ライブラリをインストールすると、次のように簡単になります。
myView.autoPinEdgesToSuperviewEdges()
@Dscheeのソリューションのフォローアップとして、ここにswift 3.0構文があります:(注意:これは私のソリューションではありません。Swift3.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]))
}
私はスーパービューを完全にカバーする必要がありました。他のものは、向きの変更中にそれをしません。そこで、20の任意のサイズの乗数を使用して、新しいものを作成しました。必要に応じて自由に変更してください。また、これは実際にはサブビューをスーパービューよりもはるかに大きくし、要件とは異なる可能性があることに注意してください。
extension UIView {
func coverSuperview() {
guard let superview = self.superview else {
assert(false, "Error! `superview` was nil – call `addSubview(_ view: UIView)` before calling `\(#function)` to fix this.")
return
}
self.translatesAutoresizingMaskIntoConstraints = false
let multiplier = CGFloat(20.0)
NSLayoutConstraint.activate([
self.heightAnchor.constraint(equalTo: superview.heightAnchor, multiplier: multiplier),
self.widthAnchor.constraint(equalTo: superview.widthAnchor, multiplier: multiplier),
self.centerXAnchor.constraint(equalTo: superview.centerXAnchor),
self.centerYAnchor.constraint(equalTo: superview.centerYAnchor),
])
}
}
私は他の答えから最高の要素を選びました:
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
NSLayoutConstraint.activate([
self.topAnchor.constraint(equalTo: superview.topAnchor),
self.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
self.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
self.trailingAnchor.constraint(equalTo: superview.trailingAnchor)
])
}
}
たとえば、カスタムUIViewで、次のように使用できます。
let myView = UIView()
myView.backgroundColor = UIColor.red
self.addSubview(myView)
myView.bindFrameToSuperviewBounds()