Skip to content

Commit

Permalink
Add MinimumSize struct and use for ButtonStyle
Browse files Browse the repository at this point in the history
  • Loading branch information
nataliq-pp committed Nov 20, 2018
1 parent 3ce96cb commit 9b5089f
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 22 deletions.
4 changes: 4 additions & 0 deletions Form.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
21A79B701DBF5DE9000D1231 /* TableViewFormStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21A79B6F1DBF5DE9000D1231 /* TableViewFormStyle.swift */; };
21D7D99F1E1CE95200CB0FE9 /* ValueLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21D7D99E1E1CE95200CB0FE9 /* ValueLabel.swift */; };
3156BAED2139366B00ECC2EC /* MixedReusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3156BAEC2139366B00ECC2EC /* MixedReusable.swift */; };
721954D821A44E450090F9E3 /* MinimumSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 721954D721A44E450090F9E3 /* MinimumSize.swift */; };
7270AFB0201FAB7C004DAAA3 /* ViewLayoutArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7270AFAF201FAB7C004DAAA3 /* ViewLayoutArea.swift */; };
B35F8AEE1F36676D00904E37 /* Collection+Changes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B35F8AED1F36676D00904E37 /* Collection+Changes.swift */; };
B35F8B4C1F3783E400904E37 /* CollectionDiffTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B35F8B4B1F3783E400904E37 /* CollectionDiffTests.swift */; };
Expand Down Expand Up @@ -132,6 +133,7 @@
21A79B6F1DBF5DE9000D1231 /* TableViewFormStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TableViewFormStyle.swift; path = Form/TableViewFormStyle.swift; sourceTree = "<group>"; };
21D7D99E1E1CE95200CB0FE9 /* ValueLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ValueLabel.swift; path = Form/ValueLabel.swift; sourceTree = "<group>"; };
3156BAEC2139366B00ECC2EC /* MixedReusable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MixedReusable.swift; path = Form/MixedReusable.swift; sourceTree = "<group>"; };
721954D721A44E450090F9E3 /* MinimumSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MinimumSize.swift; path = Form/MinimumSize.swift; sourceTree = "<group>"; };
7270AFAF201FAB7C004DAAA3 /* ViewLayoutArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewLayoutArea.swift; path = Form/ViewLayoutArea.swift; sourceTree = "<group>"; };
B35F8AED1F36676D00904E37 /* Collection+Changes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Collection+Changes.swift"; path = "Form/Collection+Changes.swift"; sourceTree = "<group>"; };
B35F8B4B1F3783E400904E37 /* CollectionDiffTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionDiffTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -287,6 +289,7 @@
F6BFAFA62090719F00CBA6B1 /* UITextField+Styling.swift */,
F6DD5CB220A0408000975242 /* ButtonStateStyle.swift */,
F64C27EB1C7B2C5B003CC378 /* ButtonStyle.swift */,
721954D721A44E450090F9E3 /* MinimumSize.swift */,
F6BFAFAC2090746C00CBA6B1 /* BarButtonStyle.swift */,
CA6755E91D4B6F1C000662FF /* SegmentedControlStyle.swift */,
1C4BA2C11E76E5D2001C0DCD /* SwitchStyle.swift */,
Expand Down Expand Up @@ -610,6 +613,7 @@
1C1EEE0D1F3308C400DFFDFE /* Selectable.swift in Sources */,
1CEED6D021341FF300893573 /* ScrollViewDelegate.swift in Sources */,
F6C0AD3D1F3DBE8300D92CDE /* Highlightable.swift in Sources */,
721954D821A44E450090F9E3 /* MinimumSize.swift in Sources */,
F65A9F9B1C7B1EC6007007B4 /* SelectView.swift in Sources */,
F6C2086B2099BE660068A5F3 /* NavigationBarPosition.swift in Sources */,
CD49499B1C199520000176D3 /* (null) in Sources */,
Expand Down
15 changes: 7 additions & 8 deletions Form/AssociatedValues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ extension NSObject {
return objc_getAssociatedObject(self, key) as? T
}

func associatedValue<T>(forKey key: UnsafeRawPointer, initial: @autoclosure () throws -> T) rethrows -> T {
func associatedValue<T>(forKey key: UnsafeRawPointer,
shouldRetainInitial: Bool = true,
initial: @autoclosure () throws -> T) rethrows -> T {
if let val: T = associatedValue(forKey: key) {
return val
}
let val = try initial()
setAssociatedValue(val, forKey: key)
setAssociatedValue(val, forKey: key, shouldBeRetained: shouldRetainInitial)
return val
}

func setWeakAssociatedValue<T>(_ val: T?, forKey key: UnsafeRawPointer) {
objc_setAssociatedObject(self, key, val, .OBJC_ASSOCIATION_ASSIGN)
}

func setAssociatedValue<T>(_ val: T?, forKey key: UnsafeRawPointer) {
objc_setAssociatedObject(self, key, val, .OBJC_ASSOCIATION_RETAIN)
func setAssociatedValue<T>(_ val: T?, forKey key: UnsafeRawPointer, shouldBeRetained: Bool = true) {
let associationPolicy: objc_AssociationPolicy = shouldBeRetained ? .OBJC_ASSOCIATION_RETAIN : .OBJC_ASSOCIATION_ASSIGN
objc_setAssociatedObject(self, key, val, associationPolicy)
}

func clearAssociatedValue(forKey key: UnsafeRawPointer) {
Expand Down
30 changes: 16 additions & 14 deletions Form/ButtonStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ import UIKit
public struct ButtonStyle: Style {
public var buttonType: UIButtonType
public var contentInsets: UIEdgeInsets
public var minimumWidth: CGFloat?
public var minimumSize: MinimumSize
public var alignment: UIControlContentHorizontalAlignment
public var states: [UIControlState: ButtonStateStyle]

public init(buttonType: UIButtonType = .custom, contentInsets: UIEdgeInsets = .zero, minimumWidth: CGFloat? = nil, alignment: UIControlContentHorizontalAlignment = .center, states: [UIControlState: ButtonStateStyle]) {
public init(buttonType: UIButtonType = .custom, contentInsets: UIEdgeInsets = .zero, minimumSize: MinimumSize = .none, alignment: UIControlContentHorizontalAlignment = .center, states: [UIControlState: ButtonStateStyle]) {
self.buttonType = buttonType
self.contentInsets = contentInsets
self.minimumWidth = minimumWidth
self.minimumSize = minimumSize
self.alignment = alignment
self.states = states
}
}

public extension ButtonStyle {
init(buttonType: UIButtonType = .custom, contentInsets: UIEdgeInsets = .zero, minimumWidth: CGFloat? = nil, alignment: UIControlContentHorizontalAlignment = .center, normal: ButtonStateStyle? = nil, highlighted: ButtonStateStyle? = nil, disabled: ButtonStateStyle? = nil, selected: ButtonStateStyle? = nil) {
self.init(buttonType: buttonType, contentInsets: contentInsets, alignment: alignment, states: .init(normal: normal, highlighted: highlighted, disabled: disabled, selected: selected))
init(buttonType: UIButtonType = .custom, contentInsets: UIEdgeInsets = .zero, minimumSize: MinimumSize = .none, alignment: UIControlContentHorizontalAlignment = .center, normal: ButtonStateStyle? = nil, highlighted: ButtonStateStyle? = nil, disabled: ButtonStateStyle? = nil, selected: ButtonStateStyle? = nil) {
self.init(buttonType: buttonType, contentInsets: contentInsets, minimumSize: minimumSize, alignment: alignment, states: .init(normal: normal, highlighted: highlighted, disabled: disabled, selected: selected))
}
}

Expand Down Expand Up @@ -122,7 +122,7 @@ private extension UIButton {
setAssociatedValue(style, forKey: &styleKey)
self.contentEdgeInsets = style.contentInsets
self.contentHorizontalAlignment = style.alignment
updateMinimumWidth(style.minimumWidth)
updateMinimumSize(style.minimumSize)

for state in UIControlState.standardStates {
let stateStyle = style.states[state]
Expand All @@ -146,16 +146,18 @@ private extension UIButton {
}
}

func updateMinimumWidth(_ minimumWidth: CGFloat?) {
if let constraint: NSLayoutConstraint = associatedValue(forKey: &widthConstraintKey) {
constraint.constant = minimumWidth ?? 0
constraint.isActive = (minimumWidth != nil)
} else if let minimumWidth = minimumWidth {
let constraint = activate(self.widthAnchor >= minimumWidth)
setWeakAssociatedValue(constraint, forKey: &widthConstraintKey)
}
func updateMinimumSize(_ minimumSize: MinimumSize) {
setConstraintConstant(minimumSize.width, forKey: &widthConstraintKey) { return self.widthAnchor >= $0 }
setConstraintConstant(minimumSize.height, forKey: &heightConstraintKey) { return self.heightAnchor >= $0 }
}

func setConstraintConstant(_ constant: CGFloat?, forKey key: UnsafeRawPointer, createConstraint: (CGFloat) -> NSLayoutConstraint) {
let constraint = associatedValue(forKey: key, shouldRetainInitial: false, initial: createConstraint(constant ?? 0))
constraint.constant = constant ?? 0
constraint.isActive = (constant != nil)
}
}

private var styleKey = 0
private var widthConstraintKey = 0
private var heightConstraintKey = 0
22 changes: 22 additions & 0 deletions Form/MinimumSize.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// MinimumSize.swift
// FlowFramework
//
// Created by Nataliya Patsovska on 2018-11-20.
//

import Foundation

public struct MinimumSize: Style {
public var width: CGFloat?
public var height: CGFloat?

public init(width: CGFloat?, height: CGFloat?) {
self.width = width
self.height = height
}
}

public extension MinimumSize {
static let none = MinimumSize(width: nil, height: nil)
}

0 comments on commit 9b5089f

Please sign in to comment.