NSLayoutConstraint
(単数形) を生成する(複数形)と呼んでいるのは少し面倒ですが、それは私constraintsWithVisualFormat...
だけだと確信しています。いずれにせよ、次の 2 つのトップレベル関数があります。
スニペット 1 (Swift 1.2)
#if os(iOS)
public typealias View = UIView
#elseif os(OSX)
public typealias View = NSView
#endif
public func NSLayoutConstraints(visualFormat: String, options: NSLayoutFormatOptions = .allZeros, views: View...) -> [NSLayoutConstraint] {
return NSLayoutConstraints(visualFormat, options: options, views: views)
}
public func NSLayoutConstraints(visualFormat: String, options: NSLayoutFormatOptions = .allZeros, views: [View] = []) -> [NSLayoutConstraint] {
if visualFormat.hasPrefix("B:") {
let h = NSLayoutConstraints("H\(dropFirst(visualFormat))", options: options, views: views)
let v = NSLayoutConstraints("V\(dropFirst(visualFormat))", options: options, views: views)
return h + v
}
var dict: [String:View] = [:]
for (i, v) in enumerate(views) {
dict["v\(i + 1)"] = v
}
let format = visualFormat.stringByReplacingOccurrencesOfString("[v]", withString: "[v1]")
return NSLayoutConstraint.constraintsWithVisualFormat(format, options: options, metrics: nil, views: dict) as! [NSLayoutConstraint]
}
次のように使用できます。
superView.addConstraints(NSLayoutConstraints("B:|[v]|", view))
つまり、ビューには自動的に名前が付けられます"v1"
("v\(views.count)"
としても参照できる最初のビューを除く"v"
)。さらに、フォーマットの前に を付けると、と"B:"
の両方の制約が生成されます。したがって、上記のコード例は、「 が常に に適合することを確認する」ことを意味します。"H:"
"V:"
view
superView
また、次の拡張機能を使用します。
スニペット 2
public extension View {
// useMask of nil will not affect the views' translatesAutoresizingMaskIntoConstraints
public func addConstraints(visualFormat: String, options: NSLayoutFormatOptions = .allZeros, useMask: Bool? = false, views: View...) {
if let useMask = useMask {
for view in views {
#if os(iOS)
view.setTranslatesAutoresizingMaskIntoConstraints(useMask)
#elseif os(OSX)
view.translatesAutoresizingMaskIntoConstraints = useMask
#endif
}
}
addConstraints(NSLayoutConstraints(visualFormat, options: options, views: views))
}
public func addSubview(view: View, constraints: String, options: NSLayoutFormatOptions = .allZeros, useMask: Bool? = false) {
addSubview(view)
addConstraints(constraints, options: options, useMask: useMask, views: view)
}
}
右下隅からの標準オフセットにボタンを追加するなど、いくつかの一般的なタスクをよりエレガントに実行できます。
superView.addSubview(button, constraints: "B:[v]-|")
たとえば、iOS プレイグラウンドでは次のようになります。
import UIKit
import XCPlayground
// paste here `snippet 1` and `snippet 2`
let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
XCPShowView("view", view)
view.backgroundColor = .orangeColor()
XCPShowView("view", view)
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
button.setTitle("bottom right", forState: .Normal)
view.addSubview(button, constraints: "B:[v]-|")