Skip to content

Commit

Permalink
Merge pull request #32 from Rightpoint/colejd/improve-inheritance-exp…
Browse files Browse the repository at this point in the history
…erience

Add full Stackable functionality for UIStackView derivatives
  • Loading branch information
Jonathan Cole committed Dec 1, 2021
2 parents 5ec0fe5 + ede08f5 commit 22b6e18
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 12 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/PackageTests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: PackageTests

on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]

jobs:
build:

runs-on: macos-latest

steps:
- uses: actions/checkout@v2
- name: Run tests
run: xcodebuild test -scheme RPStackable -destination 'platform=iOS Simulator,name=iPhone 12'
4 changes: 4 additions & 0 deletions Example/Stackable.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
B45CA0132756A40000D0AA70 /* InheritanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B45CA0122756A40000D0AA70 /* InheritanceTests.swift */; };
CC72A6DDDA4E7D960CD3D10E /* Pods_Stackable_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0285B0ADF6F8DDE8F69E6BD5 /* Pods_Stackable_Tests.framework */; };
EC5575EECB7557FB0D2EFDA7 /* Pods_Stackable_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 680380F6848D1F3CCB8C984C /* Pods_Stackable_Example.framework */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -52,6 +53,7 @@
607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
680380F6848D1F3CCB8C984C /* Pods_Stackable_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Stackable_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B32187B246E3626547391D4F /* Pods-Stackable_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Stackable_Example.debug.xcconfig"; path = "Target Support Files/Pods-Stackable_Example/Pods-Stackable_Example.debug.xcconfig"; sourceTree = "<group>"; };
B45CA0122756A40000D0AA70 /* InheritanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InheritanceTests.swift; sourceTree = "<group>"; };
C0FB5FA864AC1DCB745092FA /* Pods-Stackable_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Stackable_Tests.debug.xcconfig"; path = "Target Support Files/Pods-Stackable_Tests/Pods-Stackable_Tests.debug.xcconfig"; sourceTree = "<group>"; };
C8B792787C4B69CB30904496 /* Pods-Stackable_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Stackable_Example.release.xcconfig"; path = "Target Support Files/Pods-Stackable_Example/Pods-Stackable_Example.release.xcconfig"; sourceTree = "<group>"; };
EA360EB26E10CF4FC56BDD6E /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
Expand Down Expand Up @@ -143,6 +145,7 @@
607FACE81AFB9204008FA782 /* Tests */ = {
isa = PBXGroup;
children = (
B45CA0122756A40000D0AA70 /* InheritanceTests.swift */,
607FACEB1AFB9204008FA782 /* Tests.swift */,
00392CDF24EAF2FC001E2F99 /* MemoryTests.swift */,
607FACE91AFB9204008FA782 /* Supporting Files */,
Expand Down Expand Up @@ -364,6 +367,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B45CA0132756A40000D0AA70 /* InheritanceTests.swift in Sources */,
00392CE024EAF2FC001E2F99 /* MemoryTests.swift in Sources */,
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */,
);
Expand Down
28 changes: 28 additions & 0 deletions Example/Tests/InheritanceTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// InheritanceTests.swift
//
//
// Created by Jonathan Cole on 11/30/21.
//

import Stackable
import XCTest

class InheritingStackView: UIStackView {}

/**
In these tests, we make sure that classes inheriting from
UIStackView also have full Stackable capabilities applied.
*/
class InheritanceTests: XCTestCase {

func testDerivingClassHasStackableAddMethod() {
let stack = InheritingStackView()
stack.stackable.add([
CGFloat(0),
])

XCTAssert(true, "Passes if it compiles.")
}

}
48 changes: 48 additions & 0 deletions Example/Tests/StackableTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// StackableTests.swift
//
//
// Created by Jonathan Cole on 12/1/21.
//

@testable import Stackable
import XCTest

class StackableTests: XCTestCase {

func testHairlineConfigLogic() {
// Test Global config
UIStackView.stackable.hairlineColor = .blue
let stack1 = UIStackView()
stack1.stackable.add([
UIStackView.stackable.hairline,
])
let hairline1 = stack1.arrangedSubviews.first as! StackableHairlineView
XCTAssert(hairline1.backgroundColor == .blue)

// Test instance config
let stack2 = UIStackView()
stack2.stackable.hairlineColor = .brown
stack2.stackable.add([
UIStackView.stackable.hairline,
])
let hairline2 = stack2.arrangedSubviews.first as! StackableHairlineView
XCTAssert(hairline2.backgroundColor == .brown)

// Test per-hairline Config
let stack3 = UIStackView()
stack3.stackable.hairlineColor = .brown
stack3.stackable.add([
UIStackView.stackable.hairline,
UIStackView.stackable.hairline
.color(.yellow),
])
let hairline3 = stack3.arrangedSubviews.first as! StackableHairlineView
XCTAssert(hairline3.backgroundColor == .brown)

let hairline4 = stack3.arrangedSubviews.last as! StackableHairlineView
XCTAssert(hairline4.backgroundColor == .yellow)

}

}
4 changes: 4 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ let package = Package(
name: "Stackable",
dependencies: [],
path: "Stackable"),
.testTarget(
name: "StackableTests",
dependencies: ["Stackable"],
path: "Example/Tests"),
]
)
2 changes: 1 addition & 1 deletion Stackable/Stackable+A11y.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal enum DebugAccessibilityID {
public static let margin = "com.rightpoint.stackable.debug.margin"
}

public extension StackableExtension where ExtendedType == UIStackView {
public extension StackableExtension where ExtendedType: UIStackView {

typealias axID = StackableAccessibilityID

Expand Down
2 changes: 1 addition & 1 deletion Stackable/Stackable+Debug.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import UIKit

public extension StackableExtension where ExtendedType == UIStackView {
public extension StackableExtension where ExtendedType: UIStackView {

/// Debug API extension point
var debug: DebugStackableExtension {
Expand Down
21 changes: 15 additions & 6 deletions Stackable/Stackable+Hairlines.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public struct StackableHairline {
}

// MARK: - Public API
public extension StackableExtension where ExtendedType == UIStackView {
public extension StackableExtension where ExtendedType: UIStackView {
/// Add a hairline to the stackView
static var hairline: StackableHairline {
return .init(type: .next)
Expand Down Expand Up @@ -419,7 +419,7 @@ public extension UIStackView {
}
}

public extension StackableExtension where ExtendedType == UIStackView {
public extension StackableExtension where ExtendedType: UIStackView {

/// Instance-based `UIStackView` color override. Ultimate styling will prefer hairline-instance config first, but will prefer this over `UIStackView` static config.
var hairlineColor: UIColor? {
Expand All @@ -438,14 +438,23 @@ public extension StackableExtension where ExtendedType == UIStackView {
get { return objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.hairlineProvider) as? StackableHairlineProvider }
set { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.hairlineProvider, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

/// Static `UIStackView` color override. Ultimate styling will prefer hairline-instance config first, then `UIStackView` instance config.
static var hairlineColor: UIColor?
static var hairlineColor: UIColor? {
get { return objc_getAssociatedObject(self, &UIStackView.AssociatedKeys.hairlineColor) as? UIColor }
set { objc_setAssociatedObject(self, &UIStackView.AssociatedKeys.hairlineColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

/// Static `UIStackView` thickness override. Ultimate styling will prefer hairline-instance config first, then `UIStackView` instance config.
static var hairlineThickness: CGFloat?
static var hairlineThickness: CGFloat? {
get { return objc_getAssociatedObject(self, &UIStackView.AssociatedKeys.hairlineThickness) as? CGFloat }
set { objc_setAssociatedObject(self, &UIStackView.AssociatedKeys.hairlineThickness, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

/// Static `UIStackView` hairlineProvider override. Ultimate styling will prefer `UIStackView` instance config.
static var hairlineProvider: StackableHairlineProvider?
static var hairlineProvider: StackableHairlineProvider? {
get { return objc_getAssociatedObject(self, &UIStackView.AssociatedKeys.hairlineProvider) as? StackableHairlineProvider }
set { objc_setAssociatedObject(self, &UIStackView.AssociatedKeys.hairlineProvider, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

}
2 changes: 1 addition & 1 deletion Stackable/Stackable+Spacing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public enum StackableFlexibleSpace {

// MARK: - Public API

public extension StackableExtension where ExtendedType == UIStackView {
public extension StackableExtension where ExtendedType: UIStackView {
/// Add a space to the stackView. If added after a view, will mirror the visibility of that view.
/// - Parameter space: The size of the space.
/// - Returns: A `Stackable` that represents the space.
Expand Down
2 changes: 1 addition & 1 deletion Stackable/Stackable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ extension StackableView {

// MARK: - UIStackView Public API
extension UIView: StackableExtended {}
extension StackableExtension where ExtendedType == UIStackView {
extension StackableExtension where ExtendedType: UIStackView {

/**
Adds a `Stackable` item to the stackView.
Expand Down
2 changes: 1 addition & 1 deletion Stackable/UIStackView+Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import UIKit

// MARK: - UIStackView Utilities
extension StackableExtension where ExtendedType == UIStackView {
extension StackableExtension where ExtendedType: UIStackView {

/// Removes all `stack.arrangedSubviews` from the `UIStackView`
public func removeAllArrangedSubviews() {
Expand Down
1 change: 0 additions & 1 deletion _Pods.xcodeproj

This file was deleted.

0 comments on commit 22b6e18

Please sign in to comment.