Layout constraint helpers

This commit is contained in:
Pfeil, Scott Robert 2020-02-12 14:39:38 -05:00
parent bf8ea963b0
commit 05bda7076d
8 changed files with 64 additions and 52 deletions

View File

@ -919,7 +919,6 @@
D22479912316A9EF003FCCF9 /* Items */ = { D22479912316A9EF003FCCF9 /* Items */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D2755D7A23689C7500485468 /* TableViewCell.swift */,
01EB368923609801006832FA /* ListItemModel.swift */, 01EB368923609801006832FA /* ListItemModel.swift */,
01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */, 01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */,
012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */, 012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */,
@ -1378,6 +1377,7 @@
D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B7E2360913400A9AEDC /* Control.swift */,
D2B18B802360945C00A9AEDC /* View.swift */, D2B18B802360945C00A9AEDC /* View.swift */,
0AE14F63238315D2005417F8 /* TextField.swift */, 0AE14F63238315D2005417F8 /* TextField.swift */,
D2755D7A23689C7500485468 /* TableViewCell.swift */,
0A5D59C323AD488600EFD9E9 /* Protocols */, 0A5D59C323AD488600EFD9E9 /* Protocols */,
); );
path = BaseClasses; path = BaseClasses;

View File

@ -28,6 +28,8 @@ import UIKit
private var heroAccessoryCenter: CGPoint? private var heroAccessoryCenter: CGPoint?
private var initialSetupPerformed = false
// MARK: - Styling // MARK: - Styling
open func style(with styleString: String?) { open func style(with styleString: String?) {
guard let styleString = styleString else { guard let styleString = styleString else {
@ -102,13 +104,20 @@ import UIKit
// MARK: - Inits // MARK: - Inits
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView() initialSetup()
} }
public required init?(coder aDecoder: NSCoder) { public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
initialSetup()
}
public func initialSetup() {
if !initialSetupPerformed {
initialSetupPerformed = true
setupView() setupView()
} }
}
// MARK: - MFViewProtocol // MARK: - MFViewProtocol
public func updateView(_ size: CGFloat) { public func updateView(_ size: CGFloat) {

View File

@ -9,36 +9,52 @@
import Foundation import Foundation
public extension NSLayoutConstraint { public extension NSLayoutConstraint {
static func pinSubviewsCenter(leftView: UIView, rightView: UIView) {
guard let superView = leftView.superview else { /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned center.
static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) {
for view in views {
guard let superView = view.superview else {
return return
} }
leftView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
leftView.leftAnchor.constraint(equalTo: superView.layoutMarginsGuide.leftAnchor).isActive = true view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
leftView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: leftView.bottomAnchor).isActive = true
var constraint = leftView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
constraint.priority = .defaultLow constraint.priority = .defaultLow
constraint.isActive = true constraint.isActive = true
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: leftView.bottomAnchor) constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: 16).isActive = true
rightView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
superView.layoutMarginsGuide.rightAnchor.constraint(equalTo: rightView.rightAnchor).isActive = true
rightView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: rightView.bottomAnchor).isActive = true
constraint = rightView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: rightView.bottomAnchor)
constraint.priority = .defaultLow constraint.priority = .defaultLow
constraint.isActive = true constraint.isActive = true
} }
} }
/// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top.
static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) {
for view in views {
guard let superView = view.superview else {
return
}
view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
}
}
/// Pins a view to the left and a view to the right, flexible space in between. The super can expand depending on the taller view. Shorter views are aligned top if alignTop true, else aligned center.
static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool) {
guard let superView = leftView.superview else { return }
if alignTop {
pinViewsVerticalExpandableAlignTop([leftView, rightView])
} else {
pinViewsVerticalExpandableAlignCenter([leftView, rightView])
}
leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true
superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true
}
}

View File

@ -10,13 +10,14 @@ import UIKit
@objcMembers open class ImageHeadlineBody: View { @objcMembers open class ImageHeadlineBody: View {
let headlineBody = HeadlineBody(frame: .zero) let headlineBody = HeadlineBody(frame: .zero)
let imageView = MFLoadImageView() let imageView = MFLoadImageView(pinnedEdges: .all)
var constraintBetweenImageLabelsConstant: CGFloat = 16 var constraintBetweenImageLabelsConstant: CGFloat = 16
var constraintBetweenImageLabels: NSLayoutConstraint? var constraintBetweenImageLabels: NSLayoutConstraint?
// MARK: - MFViewProtocol // MARK: - MFViewProtocol
open override func setupView() { open override func setupView() {
super.setupView()
guard subviews.count == 0 else { guard subviews.count == 0 else {
return return
} }
@ -26,23 +27,9 @@ import UIKit
addSubview(headlineBody) addSubview(headlineBody)
addSubview(imageView) addSubview(imageView)
headlineBody.topAnchor.constraint(equalTo: topAnchor).isActive = true NSLayoutConstraint.pinViewsVerticalExpandableAlignCenter([imageView, headlineBody])
rightAnchor.constraint(equalTo: headlineBody.rightAnchor).isActive = true rightAnchor.constraint(equalTo: headlineBody.rightAnchor).isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor).isActive = true
var constraint = bottomAnchor.constraint(equalTo: headlineBody.bottomAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
imageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
imageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true imageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
imageView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: imageView.bottomAnchor).isActive = true
constraint = bottomAnchor.constraint(equalTo: imageView.bottomAnchor)
constraint.priority = UILayoutPriority(rawValue: 200)
constraint.isActive = true
constraint = imageView.topAnchor.constraint(equalTo: topAnchor)
constraint.priority = UILayoutPriority(rawValue: 200)
constraint.isActive = true
constraintBetweenImageLabels = headlineBody.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: constraintBetweenImageLabelsConstant) constraintBetweenImageLabels = headlineBody.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: constraintBetweenImageLabelsConstant)
constraintBetweenImageLabels?.isActive = true constraintBetweenImageLabels?.isActive = true

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
@objcMembers public class StackItemModel: StackItemModelProtocol, MoleculeModelProtocol { @objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol {
public static var identifier: String = "simpleStackItem" public static var identifier: String = "simpleStackItem"
public var backgroundColor: Color? public var backgroundColor: Color?
public var spacing: CGFloat? public var spacing: CGFloat?

View File

@ -27,7 +27,7 @@ import UIKit
headlineBodyLink.headlineBody.styleListItem() headlineBodyLink.headlineBody.styleListItem()
addSubview(headlineBodyLink) addSubview(headlineBodyLink)
addSubview(toggle) addSubview(toggle)
NSLayoutConstraint.pinSubviewsCenter(leftView: headlineBodyLink, rightView: toggle) NSLayoutConstraint.pinViews(leftView: headlineBodyLink, rightView: toggle, alignTop: false)
} }
// MARK: - MVMCoreUIMoleculeViewProtoco // MARK: - MVMCoreUIMoleculeViewProtoco

View File

@ -31,7 +31,7 @@ import UIKit
view.addSubview(headlineBody) view.addSubview(headlineBody)
view.addSubview(toggle) view.addSubview(toggle)
NSLayoutConstraint.pinSubviewsCenter(leftView: headlineBody, rightView: toggle) NSLayoutConstraint.pinViews(leftView: headlineBody, rightView: toggle, alignTop: false)
} }
// MARK:- ModelMoleculeViewProtocol // MARK:- ModelMoleculeViewProtocol

View File

@ -28,7 +28,7 @@ import UIKit
addSubview(label) addSubview(label)
addSubview(toggle) addSubview(toggle)
label.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) label.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
NSLayoutConstraint.pinSubviewsCenter(leftView: label, rightView: toggle) NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false)
} }
// MARK:- ModelMoleculeViewProtocol // MARK:- ModelMoleculeViewProtocol