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,12 +104,19 @@ 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)
setupView() initialSetup()
}
public func initialSetup() {
if !initialSetupPerformed {
initialSetupPerformed = true
setupView()
}
} }
// MARK: - MFViewProtocol // MARK: - MFViewProtocol

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.
return static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) {
for view in views {
guard let superView = view.superview else {
return
}
view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
} }
leftView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true }
leftView.leftAnchor.constraint(equalTo: superView.layoutMarginsGuide.leftAnchor).isActive = true
leftView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: leftView.bottomAnchor).isActive = true
var constraint = leftView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top.
constraint.priority = .defaultLow static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) {
constraint.isActive = true 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
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: leftView.bottomAnchor) let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
constraint.priority = .defaultLow constraint.priority = .defaultLow
constraint.isActive = true constraint.isActive = true
}
}
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: 16).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) {
rightView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true guard let superView = leftView.superview else { return }
superView.layoutMarginsGuide.rightAnchor.constraint(equalTo: rightView.rightAnchor).isActive = true if alignTop {
rightView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true pinViewsVerticalExpandableAlignTop([leftView, rightView])
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: rightView.bottomAnchor).isActive = true } else {
pinViewsVerticalExpandableAlignCenter([leftView, rightView])
constraint = rightView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) }
constraint.priority = .defaultLow leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true
constraint.isActive = true superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: rightView.bottomAnchor)
constraint.priority = .defaultLow
constraint.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