Skip to content

Commit

Permalink
Split DSL and Kit API to separate Targets (#10)
Browse files Browse the repository at this point in the history
* Separate DSL and Kit libraries

* keep only UIViewKit

* Remove labeling of constraints created with DSL in case of interference with custom identifiers

* Change some function names and reorganize them

* Add swift-snapshot-testing to test target

* Fix file header content

* Move UIViewKitDevelopmentViews to testTarget and update Carthage project

* push toto test

* remove file toto from framework

* fix carthage fix archive build

* fix missing public

* test type in extension not published

* Fix api scoped with debug

* Fix build errors

* trying to figure out diff between carthage build and swiftpm

* Improving package definition

* remove .swiftpm from tracking and update .gitignore

* update swiftpm and carthage support

* skip ui snapshot tests

* remove support for uisnapshot testing
  • Loading branch information
Adobels authored Feb 16, 2024
1 parent beb85d1 commit f44eb1d
Show file tree
Hide file tree
Showing 48 changed files with 766 additions and 905 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ playground.xcworkspace
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.swiftpm

.build/

Expand Down
7 changes: 0 additions & 7 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

This file was deleted.

92 changes: 0 additions & 92 deletions .swiftpm/xcode/xcshareddata/xcschemes/UIViewKit.xcscheme

This file was deleted.

11 changes: 4 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,16 @@ let package = Package(
.iOS(.v13)
],
products: [
.library(name: "UIViewKit", targets: ["UIViewKit"]),
// .library(name: "UIViewKitDevelopmentViews", targets: ["UIViewKitDevelopmentViews"])
.library(name: "UIViewKit", targets: ["UIViewKit"])
],
targets: [
.target(
name: "UIViewKit"
),
.target(
name: "UIViewKitDevelopmentViews",
dependencies: ["UIViewKit"]
),
.testTarget(
name: "UIViewKitTests",
dependencies: ["UIViewKit", "UIViewKitDevelopmentViews"])
dependencies: [
"UIViewKit"
])
]
)
83 changes: 83 additions & 0 deletions Sources/UIViewKit/IBConstraints/IBConstraints.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// IBConstraints.swift
// UIViewKit
//
// Created by Blazej SLEBODA on 30/01/2024.
//

import UIKit

public final class IBConstraints {

private init() {}

public static func create(from: UIView, to: UIView, guide: LayoutGuide, anchors: ViewAnchor...) -> [NSLayoutConstraint] {
createConstraints(from: from, to: to, guide: guide, anchors: anchors)
}

static func createConstraints(from: UIView, to: UIView, guide: LayoutGuide, anchors: [ViewAnchor]) -> [NSLayoutConstraint] {
switch guide {
case .view:
return createConstraints(from: from, to: to, anchors: anchors)
case .viewMargins:
return createConstraints(from: from, to: to.layoutMarginsGuide, anchors: anchors)
case .viewSafeArea:
return createConstraints(from: from, to: to.safeAreaLayoutGuide, anchors: anchors)
}
}

private static func createConstraints(from view: UIView, to target: Any, anchors: [ViewAnchor]) -> [NSLayoutConstraint] {
var constraints: [NSLayoutConstraint] = []
// swiftlint:disable force_cast
for anchor in anchors {
switch anchor {
case .left(let value):
constraints.append(view.leftAnchor.constraint(equalTo: (target as? UILayoutGuide)?.leftAnchor ?? (target as! UIView).leftAnchor, constant: value))
case .right(let value):
constraints.append(view.rightAnchor.constraint(equalTo: (target as? UILayoutGuide)?.rightAnchor ?? (target as! UIView).rightAnchor, constant: value))
case .top(let value):
constraints.append(view.topAnchor.constraint(equalTo: (target as? UILayoutGuide)?.topAnchor ?? (target as! UIView).topAnchor, constant: value))
case .bottom(let value):
constraints.append(view.bottomAnchor.constraint(equalTo: (target as? UILayoutGuide)?.bottomAnchor ?? (target as! UIView).bottomAnchor, constant: value))
case .centerX(let value):
constraints.append(view.centerXAnchor.constraint(equalTo: (target as? UILayoutGuide)?.centerXAnchor ?? (target as! UIView).centerXAnchor, constant: value))
case .centerY(let value):
constraints.append(view.centerYAnchor.constraint(equalTo: (target as? UILayoutGuide)?.centerYAnchor ?? (target as! UIView).centerYAnchor, constant: value))
case .leading(let value):
constraints.append(view.leadingAnchor.constraint(equalTo: (target as? UILayoutGuide)?.leadingAnchor ?? (target as! UIView).leadingAnchor, constant: value))
case .trailing(let value):
constraints.append(view.trailingAnchor.constraint(equalTo: (target as? UILayoutGuide)?.trailingAnchor ?? (target as! UIView).trailingAnchor, constant: value))
case .all:
constraints.append(contentsOf: createConstraints(from: view, to: target, anchors: [.top, .bottom, .left, .right]))
}
}
// swiftlint:enable force_cast
return constraints
}

public enum LayoutGuide {
case view
case viewMargins
case viewSafeArea
}

public enum ViewAnchor {
case left(CGFloat)
case right(CGFloat)
case top(CGFloat)
case bottom(CGFloat)
case centerX(CGFloat)
case centerY(CGFloat)
case leading(CGFloat)
case trailing(CGFloat)
case all
static public var left: ViewAnchor { return .left(.zero) }
static public var right: ViewAnchor { return .right(.zero) }
static public var top: ViewAnchor { return .top(.zero) }
static public var bottom: ViewAnchor { return .bottom(.zero) }
static public var centerX: ViewAnchor { return .centerX(.zero) }
static public var centerY: ViewAnchor { return .centerY(.zero) }
static public var leading: ViewAnchor { return .leading(.zero) }
static public var trailing: ViewAnchor { return .trailing(.zero) }
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
//
// UIViewDebug.swift
// IBDebug.swift
// UIViewKit
//
// Created by Blazej SLEBODA on 19/09/2023.
//

import UIKit

public struct UIViewDebug {
public final class IBDebug {

private init() {}

public static func showColors(of view: UIView, includeGivenView: Bool, includeUIKitPrivateViews: Bool) {
public static func showColors(of view: UIView, includeGivenView: Bool = true, includeUIKitPrivateViews: Bool = false) {
let colors = [UIColor.red, .blue, .brown, .cyan, .darkGray, .magenta, .green, .lightGray, .orange, .purple, .yellow]
if includeGivenView {
view.layer.borderWidth = 1
Expand All @@ -19,7 +21,7 @@ public struct UIViewDebug {
}
}

public static func showFrames(of view: UIView, includeGivenView: Bool, includeUIKitPrivateViews: Bool) {
public static func showFrames(of view: UIView, includeGivenView: Bool = true, includeUIKitPrivateViews: Bool = false) {
if includeGivenView {
view.layer.borderWidth = 1
}
Expand All @@ -44,9 +46,9 @@ public struct UIViewDebug {
return all
}

public static func prettyStringAllSubviews(of view: UIView, includeItself: Bool, includeUIKitPrivateViews: Bool) -> String {
public static func allSubviewsPrettyString(of view: UIView, includeGivenView: Bool, includeUIKitPrivateViews: Bool = false) -> String {
let allSubviews: [UIView]
if includeItself {
if includeGivenView {
allSubviews = [view] + self.allSubviews(of: view, includeUIKitPrivateViews: includeUIKitPrivateViews)
} else {
allSubviews = self.allSubviews(of: view, includeUIKitPrivateViews: includeUIKitPrivateViews)
Expand All @@ -71,29 +73,27 @@ public struct UIViewDebug {
return output
}

public static func prettyPrintAllSubviews(of view: UIView, includeItself: Bool, includeUIKitPrivateViews: Bool) {
print(prettyStringAllSubviews(of: view, includeItself: includeItself, includeUIKitPrivateViews: includeUIKitPrivateViews), separator: "\n")
public static func allSubviewsPrettyPrint(of view: UIView, includeGivenView: Bool, includeUIKitPrivateViews: Bool = false) {
print(allSubviewsPrettyString(of: view, includeGivenView: includeGivenView, includeUIKitPrivateViews: includeUIKitPrivateViews), separator: "\n")
}
}

extension UIViewDebug {

public static func showViewsWhichHasAmbiguousLayout(for view: UIView) {
view.allSubviews.forEach { subview in
if subview is DebugView {

IBHelper.allSubviews(of: view).forEach { subview in
if subview is UIDebugView {
subview.removeConstraints(subview.constraints)
subview.removeFromSuperview()
}
subview.exerciseAmbiguityInLayout()
if subview.hasAmbiguousLayout {
let debugView = DebugView()
let debugView = UIDebugView()
subview.addSubview(debugView)
debugView.frame = .init(origin: .zero, size: subview.frame.size)
}
}
}

class DebugView: UIView {
private class UIDebugView: UIView {

override init(frame: CGRect) {
super.init(frame: frame)
Expand All @@ -107,11 +107,10 @@ extension UIViewDebug {
}
}

extension UIView {

var allSubviews: [UIView] {
subviews.flatMap {
[$0] + $0.allSubviews
final class IBHelper {
static func allSubviews(of view: UIView) -> [UIView] {
view.subviews.flatMap {
[$0] + IBHelper.allSubviews(of: $0)
}
}
}
44 changes: 44 additions & 0 deletions Sources/UIViewKit/IBPreviews/IBPreview+FreeFormView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// IBPreview+FreeFormView.swift
// UIViewKit
//
// Created by Blazej SLEBODA on 14/11/2023.
//

import UIKit
import SwiftUI

extension IBPreview {

@available(iOS 13.0, *)
public struct FreeFormView: UIViewControllerRepresentable {

private let viewMaker: (Context) -> UIView

public init(_ view: UIView) {
self.viewMaker = { _ in
view
}
}

public init(viewMaker: @escaping (Context) -> UIView) {
self.viewMaker = viewMaker
}

public func makeUIViewController(context: Context) -> UIViewController {
let controller = UIViewController()
let view = viewMaker(context)
controller.view.addSubview(view)
view.frame = controller.view.bounds
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
view.translatesAutoresizingMaskIntoConstraints = true

let freeFormContainer = ContainerViewController()
_ = freeFormContainer.view
freeFormContainer.childViewController = controller
return freeFormContainer
}

public func updateUIViewController(_ uiViewController: UIViewController, context: Context) { }
}
}
Loading

0 comments on commit f44eb1d

Please sign in to comment.