updated submodules

This commit is contained in:
Balackburn
2023-06-27 14:19:24 +02:00
parent 767b3b7798
commit 036ad6b006
1412 changed files with 18 additions and 83422 deletions

1
Tweaks/Alderis Submodule

Submodule Tweaks/Alderis added at 7992b3b57e

View File

@@ -1,16 +0,0 @@
# Crap
.DS_Store
# Xcode
*.pbxuser
!default.pbxuser
xcuserdata
*.xccheckout
*.xcuserstate
# Carthage
Carthage/
# Theos
.theos
packages/

View File

@@ -1,36 +0,0 @@
clean: true
author: HASHBANG Productions
author_url: https://hbang.github.io/
github_url: https://github.com/hbang/Alderis
root_url: https://hbang.github.io/Alderis/
dash_url: https://hbang.github.io/Alderis/docsets/Alderis.xml
documentation: info/*.md
hide_documentation_coverage: true
custom_categories:
- name: "Guides"
children:
- "Preference Bundles"
- "Migrating to 1.1"
- name: "Color Picker"
children:
- ColorPickerViewController
- ColorPickerConfiguration
- ColorPickerDelegate
- ColorPickerTab
- name: "UI Components"
children:
- ColorWell
- name: "Extensions"
children:
- UIColor
- ColorPropertyListValue
- String
- Array
- name: "Deprecated"
children:
- ColorPickerCircleView

View File

@@ -1,61 +0,0 @@
disabled_rules:
- trailing_comma
- nesting
- fallthrough
- shorthand_operator
- todo
- large_tuple
- identifier_name
- type_name
- type_body_length
# TODO: Why is vertical_parameter_alignment giving false positives?
- vertical_parameter_alignment
- vertical_parameter_alignment_on_call
# TODO: Enable when removing support for older Swift versions (<5.6)
- unavailable_condition
opt_in_rules:
- closure_end_indentation
- closure_spacing
- contains_over_first_not_nil
- empty_count
- explicit_init
- fatal_error_message
- first_where
- joined_default_parameter
- literal_expression_end_indentation
- overridden_super_call
- prohibited_super_call
- sorted_first_last
- unneeded_parentheses_in_closure_argument
- vertical_parameter_alignment_on_call
- yoda_condition
- nslocalizedstring_key
- unused_setter_value
custom_rules:
comment_whitespace:
name: "Comment Whitespace"
regex: //\S
match_kinds: comment
message: "Comments must begin with a whitespace character"
spaces_not_tabs:
name: "Tabs not Spaces"
regex: ^( )
message: "Use tabs instead of spaces"
point_zero:
name: "Point Zero"
regex: '(?<!iOS\s)(?<!macOS\s)(?<!\.)\b[\d_]+\.0\b'
match_kinds:
- number
- attribute.builtin
message: "Don't add a .0 to the end of floating point literals"
color_init:
name: "Color Initializer"
regex: 'UIColor\(red: (.+), green: \1, blue: \1, alpha: .+\)'
message: "Use UIColor(white:alpha:)"
force_try: warning
force_cast: warning
function_body_length: 200
line_length: 200
file_length: 450
cyclomatic_complexity: 12
function_parameter_count: 7

View File

@@ -1,30 +0,0 @@
Pod::Spec.new do |spec|
spec.name = "Alderis"
spec.version = "1.2.0"
spec.summary = "A fresh new color picker, with a gentle, fun, and dead simple user interface."
spec.description = <<-DESC
Alderis is a fresh new color picker, with a gentle, fun, and dead simple user
interface. It aims to incorporate the usual elements of a color picker, in a way
that users will find easy and fun to use.
The user can start by selecting a color they like on the initial color palette
tab, and either accept it, or refine it using the color wheel and adjustment
sliders found on the two other tabs.
DESC
spec.homepage = "https://github.com/hbang/Alderis"
spec.screenshots = "https://github.com/hbang/Alderis/raw/main/screenshots/alderis-1.jpg",
"https://github.com/hbang/Alderis/raw/main/screenshots/alderis-2.jpg",
"https://github.com/hbang/Alderis/raw/main/screenshots/alderis-3.jpg",
"https://github.com/hbang/Alderis/raw/main/screenshots/alderis-4.jpg"
spec.license = "Apache License, Version 2.0"
spec.author = "HASHBANG Productions"
spec.social_media_url = "https://twitter.com/hashbang"
spec.swift_versions = "5.0"
spec.platform = :ios, "12.0"
spec.source = { :git => "https://github.com/hbang/Alderis.git", :tag => "#{spec.version}" }
spec.requires_arc = true
spec.source_files = [ "Alderis/*.swift", "Alderis/*.h" ]
spec.resource_bundles = { "Alderis" => "Alderis/Assets-ios12.xcassets" }
end

View File

@@ -1,482 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
4E1C741328266C5900227EC3 /* UIFontDescriptorAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741228266C5900227EC3 /* UIFontDescriptorAdditions.swift */; };
4E1C74172826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C74162826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift */; };
4E1C741928276D5600227EC3 /* TextViewLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741828276D5600227EC3 /* TextViewLabel.swift */; };
4E1C741B2827829E00227EC3 /* AccessibilityComplianceLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741A2827829E00227EC3 /* AccessibilityComplianceLabel.swift */; };
4E1C741D2827882600227EC3 /* AccessibilityContrastSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741C2827882600227EC3 /* AccessibilityContrastSelector.swift */; };
4E1C741F2827B3C800227EC3 /* UIFloat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741E2827B3C800227EC3 /* UIFloat.swift */; };
4E1C74212827B8F800227EC3 /* NSBeep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C74202827B8F800227EC3 /* NSBeep.swift */; };
4E2E6C06282BD5990089E4FB /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2E6C05282BD5990089E4FB /* GradientView.swift */; };
569C25522427F57000022C60 /* ColorPickerTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C25512427F57000022C60 /* ColorPickerTabViewController.swift */; };
569C25582428346900022C60 /* ColorPickerMapSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C25572428346900022C60 /* ColorPickerMapSlider.swift */; };
56C74667242F722A003ED00A /* ColorPickerSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56C74666242F722A003ED00A /* ColorPickerSlider.swift */; };
56C74669242F75E3003ED00A /* ColorPickerNumericSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56C74668242F75E3003ED00A /* ColorPickerNumericSlider.swift */; };
94A2368C252B5951002B5D0B /* UIColorAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94A2368B252B5951002B5D0B /* UIColorAdditions.swift */; };
CF73D33A241F9C23000B1B10 /* Alderis.h in Headers */ = {isa = PBXBuildFile; fileRef = CF73D338241F9C23000B1B10 /* Alderis.h */; settings = {ATTRIBUTES = (Public, ); }; };
CF73D344241F9C31000B1B10 /* ColorWell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF73D32D241E49EE000B1B10 /* ColorWell.swift */; };
CF73D345241F9C31000B1B10 /* ColorPickerMapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70280241CBDE700083903 /* ColorPickerMapViewController.swift */; };
CF73D346241F9C31000B1B10 /* ColorPickerSlidersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70282241CC88D00083903 /* ColorPickerSlidersViewController.swift */; };
CF73D347241F9C31000B1B10 /* ColorPickerWheelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70288241D0E7300083903 /* ColorPickerWheelView.swift */; };
CF73D348241F9C31000B1B10 /* ColorPickerInnerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE7027B241A62ED00083903 /* ColorPickerInnerViewController.swift */; };
CF73D34A241F9C31000B1B10 /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70273241A4C5500083903 /* ColorPickerViewController.swift */; };
CF73D34B241F9C31000B1B10 /* ColorPickerSwatchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE7027E241B984600083903 /* ColorPickerSwatchViewController.swift */; };
CF73D34C241F9C4D000B1B10 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF73D32B241E4720000B1B10 /* Color.swift */; };
CF73D351241F9FB3000B1B10 /* ColorPickerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF73D350241F9FB3000B1B10 /* ColorPickerDelegate.swift */; };
CF7750B72520D3B50069CC57 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750B62520D3B50069CC57 /* Assets.swift */; };
CF7750BE252203630069CC57 /* DialogButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750BD252203630069CC57 /* DialogButton.swift */; };
CF7750CF252433680069CC57 /* ColorPickerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750CE252433680069CC57 /* ColorPickerConfiguration.swift */; };
CF7750D62524615D0069CC57 /* SeparatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750D52524615D0069CC57 /* SeparatorView.swift */; };
CF775122252852460069CC57 /* AlderisSDKCompatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = CF775121252852110069CC57 /* AlderisSDKCompatibility.h */; settings = {ATTRIBUTES = (Public, ); }; };
CF79DA31251723C500F17BCB /* BottomSheetTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF79DA30251723C500F17BCB /* BottomSheetTransition.swift */; };
CFAFFC9124277CEE005AD4C1 /* Assets-ios12.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CFAFFC9024277CEE005AD4C1 /* Assets-ios12.xcassets */; platformFilter = ios; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
4E1C741228266C5900227EC3 /* UIFontDescriptorAdditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontDescriptorAdditions.swift; sourceTree = "<group>"; };
4E1C74162826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerAccessibilityViewController.swift; sourceTree = "<group>"; };
4E1C741828276D5600227EC3 /* TextViewLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewLabel.swift; sourceTree = "<group>"; };
4E1C741A2827829E00227EC3 /* AccessibilityComplianceLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityComplianceLabel.swift; sourceTree = "<group>"; };
4E1C741C2827882600227EC3 /* AccessibilityContrastSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityContrastSelector.swift; sourceTree = "<group>"; };
4E1C741E2827B3C800227EC3 /* UIFloat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFloat.swift; sourceTree = "<group>"; };
4E1C74202827B8F800227EC3 /* NSBeep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSBeep.swift; sourceTree = "<group>"; };
4E2E6C05282BD5990089E4FB /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
569C25512427F57000022C60 /* ColorPickerTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerTabViewController.swift; sourceTree = "<group>"; };
569C25572428346900022C60 /* ColorPickerMapSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerMapSlider.swift; sourceTree = "<group>"; };
56C74666242F722A003ED00A /* ColorPickerSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerSlider.swift; sourceTree = "<group>"; };
56C74668242F75E3003ED00A /* ColorPickerNumericSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerNumericSlider.swift; sourceTree = "<group>"; };
94A2368B252B5951002B5D0B /* UIColorAdditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorAdditions.swift; sourceTree = "<group>"; };
CF73D32B241E4720000B1B10 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
CF73D32D241E49EE000B1B10 /* ColorWell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorWell.swift; sourceTree = "<group>"; };
CF73D336241F9C23000B1B10 /* Alderis.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alderis.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CF73D338241F9C23000B1B10 /* Alderis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Alderis.h; sourceTree = "<group>"; };
CF73D339241F9C23000B1B10 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CF73D350241F9FB3000B1B10 /* ColorPickerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerDelegate.swift; sourceTree = "<group>"; };
CF7750B62520D3B50069CC57 /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = "<group>"; };
CF7750BD252203630069CC57 /* DialogButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogButton.swift; sourceTree = "<group>"; };
CF7750CE252433680069CC57 /* ColorPickerConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPickerConfiguration.swift; sourceTree = "<group>"; };
CF7750D52524615D0069CC57 /* SeparatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeparatorView.swift; sourceTree = "<group>"; };
CF775121252852110069CC57 /* AlderisSDKCompatibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AlderisSDKCompatibility.h; sourceTree = "<group>"; };
CF79DA30251723C500F17BCB /* BottomSheetTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomSheetTransition.swift; sourceTree = "<group>"; };
CFAFFC9024277CEE005AD4C1 /* Assets-ios12.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Assets-ios12.xcassets"; sourceTree = "<group>"; };
CFE70273241A4C5500083903 /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = "<group>"; };
CFE7027B241A62ED00083903 /* ColorPickerInnerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerInnerViewController.swift; sourceTree = "<group>"; };
CFE7027E241B984600083903 /* ColorPickerSwatchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerSwatchViewController.swift; sourceTree = "<group>"; };
CFE70280241CBDE700083903 /* ColorPickerMapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerMapViewController.swift; sourceTree = "<group>"; };
CFE70282241CC88D00083903 /* ColorPickerSlidersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerSlidersViewController.swift; sourceTree = "<group>"; };
CFE70288241D0E7300083903 /* ColorPickerWheelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerWheelView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CF73D333241F9C23000B1B10 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
CF39D435222BC07C001EF57F = {
isa = PBXGroup;
children = (
CF73D337241F9C23000B1B10 /* Alderis */,
CF39D43F222BC07C001EF57F /* Products */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 1;
};
CF39D43F222BC07C001EF57F /* Products */ = {
isa = PBXGroup;
children = (
CF73D336241F9C23000B1B10 /* Alderis.framework */,
);
name = Products;
sourceTree = "<group>";
};
CF73D337241F9C23000B1B10 /* Alderis */ = {
isa = PBXGroup;
children = (
CF73D338241F9C23000B1B10 /* Alderis.h */,
CF775121252852110069CC57 /* AlderisSDKCompatibility.h */,
CF7750B62520D3B50069CC57 /* Assets.swift */,
CF79DA30251723C500F17BCB /* BottomSheetTransition.swift */,
CF73D32B241E4720000B1B10 /* Color.swift */,
CFE70273241A4C5500083903 /* ColorPickerViewController.swift */,
CF7750CE252433680069CC57 /* ColorPickerConfiguration.swift */,
CF73D350241F9FB3000B1B10 /* ColorPickerDelegate.swift */,
CFE7027B241A62ED00083903 /* ColorPickerInnerViewController.swift */,
569C25512427F57000022C60 /* ColorPickerTabViewController.swift */,
56C74666242F722A003ED00A /* ColorPickerSlider.swift */,
CFE7027E241B984600083903 /* ColorPickerSwatchViewController.swift */,
569C25572428346900022C60 /* ColorPickerMapSlider.swift */,
CFE70280241CBDE700083903 /* ColorPickerMapViewController.swift */,
CFE70288241D0E7300083903 /* ColorPickerWheelView.swift */,
CFE70282241CC88D00083903 /* ColorPickerSlidersViewController.swift */,
56C74668242F75E3003ED00A /* ColorPickerNumericSlider.swift */,
4E1C74162826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift */,
4E1C741A2827829E00227EC3 /* AccessibilityComplianceLabel.swift */,
4E1C741C2827882600227EC3 /* AccessibilityContrastSelector.swift */,
CF73D32D241E49EE000B1B10 /* ColorWell.swift */,
CF7750BD252203630069CC57 /* DialogButton.swift */,
CF7750D52524615D0069CC57 /* SeparatorView.swift */,
4E2E6C05282BD5990089E4FB /* GradientView.swift */,
94A2368B252B5951002B5D0B /* UIColorAdditions.swift */,
4E1C741228266C5900227EC3 /* UIFontDescriptorAdditions.swift */,
4E1C741E2827B3C800227EC3 /* UIFloat.swift */,
4E1C741828276D5600227EC3 /* TextViewLabel.swift */,
4E1C74202827B8F800227EC3 /* NSBeep.swift */,
CF73D339241F9C23000B1B10 /* Info.plist */,
CFAFFC9024277CEE005AD4C1 /* Assets-ios12.xcassets */,
);
path = Alderis;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
CF73D331241F9C23000B1B10 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
CF73D33A241F9C23000B1B10 /* Alderis.h in Headers */,
CF775122252852460069CC57 /* AlderisSDKCompatibility.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
CF73D335241F9C23000B1B10 /* Alderis */ = {
isa = PBXNativeTarget;
buildConfigurationList = CF73D340241F9C23000B1B10 /* Build configuration list for PBXNativeTarget "Alderis" */;
buildPhases = (
CF73D331241F9C23000B1B10 /* Headers */,
CF73D332241F9C23000B1B10 /* Sources */,
CF73D333241F9C23000B1B10 /* Frameworks */,
CF73D334241F9C23000B1B10 /* Resources */,
CF77511225281F7E0069CC57 /* SwiftLint */,
);
buildRules = (
);
dependencies = (
);
name = Alderis;
productName = Alderis;
productReference = CF73D336241F9C23000B1B10 /* Alderis.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CF39D436222BC07C001EF57F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1330;
ORGANIZATIONNAME = "HASHBANG Productions";
TargetAttributes = {
CF73D335241F9C23000B1B10 = {
CreatedOnToolsVersion = 11.3.1;
};
};
};
buildConfigurationList = CF39D439222BC07C001EF57F /* Build configuration list for PBXProject "Alderis" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CF39D435222BC07C001EF57F;
productRefGroup = CF39D43F222BC07C001EF57F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CF73D335241F9C23000B1B10 /* Alderis */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CF73D334241F9C23000B1B10 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CFAFFC9124277CEE005AD4C1 /* Assets-ios12.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
CF77511225281F7E0069CC57 /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = SwiftLint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export PATH=$PATH:/opt/homebrew/bin\nif which swiftlint >/dev/null; then\n\tswiftlint\nelse\n\techo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CF73D332241F9C23000B1B10 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CF73D34B241F9C31000B1B10 /* ColorPickerSwatchViewController.swift in Sources */,
CF7750BE252203630069CC57 /* DialogButton.swift in Sources */,
4E1C741928276D5600227EC3 /* TextViewLabel.swift in Sources */,
CF73D347241F9C31000B1B10 /* ColorPickerWheelView.swift in Sources */,
CF7750D62524615D0069CC57 /* SeparatorView.swift in Sources */,
CF73D34C241F9C4D000B1B10 /* Color.swift in Sources */,
94A2368C252B5951002B5D0B /* UIColorAdditions.swift in Sources */,
569C25582428346900022C60 /* ColorPickerMapSlider.swift in Sources */,
4E2E6C06282BD5990089E4FB /* GradientView.swift in Sources */,
CF73D344241F9C31000B1B10 /* ColorWell.swift in Sources */,
CF7750B72520D3B50069CC57 /* Assets.swift in Sources */,
CF73D348241F9C31000B1B10 /* ColorPickerInnerViewController.swift in Sources */,
56C74667242F722A003ED00A /* ColorPickerSlider.swift in Sources */,
4E1C74212827B8F800227EC3 /* NSBeep.swift in Sources */,
4E1C74172826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift in Sources */,
4E1C741D2827882600227EC3 /* AccessibilityContrastSelector.swift in Sources */,
CF73D345241F9C31000B1B10 /* ColorPickerMapViewController.swift in Sources */,
CF79DA31251723C500F17BCB /* BottomSheetTransition.swift in Sources */,
4E1C741328266C5900227EC3 /* UIFontDescriptorAdditions.swift in Sources */,
CF73D34A241F9C31000B1B10 /* ColorPickerViewController.swift in Sources */,
CF7750CF252433680069CC57 /* ColorPickerConfiguration.swift in Sources */,
56C74669242F75E3003ED00A /* ColorPickerNumericSlider.swift in Sources */,
569C25522427F57000022C60 /* ColorPickerTabViewController.swift in Sources */,
4E1C741F2827B3C800227EC3 /* UIFloat.swift in Sources */,
CF73D351241F9FB3000B1B10 /* ColorPickerDelegate.swift in Sources */,
CF73D346241F9C31000B1B10 /* ColorPickerSlidersViewController.swift in Sources */,
4E1C741B2827829E00227EC3 /* AccessibilityComplianceLabel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
CF39D452222BC07E001EF57F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
CF39D453222BC07E001EF57F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
CF73D341241F9C23000B1B10 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CURRENT_PROJECT_VERSION = 3;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Alderis/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = ws.hbang.Alderis;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
CF73D342241F9C23000B1B10 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CURRENT_PROJECT_VERSION = 3;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Alderis/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = ws.hbang.Alderis;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = NO;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CF39D439222BC07C001EF57F /* Build configuration list for PBXProject "Alderis" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF39D452222BC07E001EF57F /* Debug */,
CF39D453222BC07E001EF57F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CF73D340241F9C23000B1B10 /* Build configuration list for PBXNativeTarget "Alderis" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF73D341241F9C23000B1B10 /* Debug */,
CF73D342241F9C23000B1B10 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CF39D436222BC07C001EF57F /* Project object */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Alderis Demo.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1330"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF73D335241F9C23000B1B10"
BuildableName = "Alderis.framework"
BlueprintName = "Alderis"
ReferencedContainer = "container:Alderis.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF73D335241F9C23000B1B10"
BuildableName = "Alderis.framework"
BlueprintName = "Alderis"
ReferencedContainer = "container:Alderis.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,77 +0,0 @@
//
// AccessibilityComplianceLabel.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class AccessibilityComplianceLabel: UIView {
var text: String {
get { label.text! }
set { label.text = newValue }
}
var isCompliant = false {
didSet { updateState() }
}
private let tickImage = Assets.systemImage(named: "checkmark.circle.fill")
private let crossImage = Assets.systemImage(named: "xmark.circle.fill")
private var imageView: UIImageView!
private var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
let font = UIFont.systemFont(ofSize: UIFloat(16), weight: .medium)
imageView = UIImageView()
if #available(iOS 13, *) {
imageView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(font: font, scale: .small)
}
label = UILabel()
label.font = font
let stackView = UIStackView(arrangedSubviews: [imageView, label])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.alignment = .center
stackView.spacing = UIFloat(6)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: self.topAnchor),
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
}
convenience init(text: String) {
self.init(frame: .zero)
self.text = text
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func updateState() {
let color = isCompliant ? Assets.green : Assets.red
tintColor = color
accessibilityLabel = "\(text): \(isCompliant ? "Compliant" : "Not compliant")"
imageView.image = isCompliant ? tickImage : crossImage
}
override func tintColorDidChange() {
super.tintColorDidChange()
label.textColor = tintColor
}
}

View File

@@ -1,91 +0,0 @@
//
// AccessibilityContrastSelector.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class AccessibilityContrastSelector: UIView {
enum Mode: Int, CaseIterable {
case color, black, white
var label: String {
switch self {
case .color: return "Color"
case .black: return "Black"
case .white: return "White"
}
}
func color(withColor color: Color) -> Color {
switch self {
case .color: return color
case .black: return .black
case .white: return .white
}
}
}
var text: String {
get { label.text! }
set { label.text = newValue }
}
var value: Mode = .white {
didSet {
if segmentedControl.selectedSegmentIndex != value.rawValue {
segmentedControl.selectedSegmentIndex = value.rawValue
handleChange?(value)
}
}
}
var handleChange: ((Mode) -> Void)?
private var label: UILabel!
private var segmentedControl: UISegmentedControl!
override init(frame: CGRect) {
super.init(frame: frame)
label = UILabel()
label.font = UIFont.systemFont(ofSize: UIFloat(16), weight: .medium)
segmentedControl = UISegmentedControl(items: Mode.allCases.map(\.label))
segmentedControl.addTarget(self, action: #selector(handleValueChanged), for: .valueChanged)
let stackView = UIStackView(arrangedSubviews: [label, UIView(), segmentedControl])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.alignment = .center
stackView.distribution = .fill
stackView.spacing = UIFloat(5)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: self.topAnchor),
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init(text: String, value: Mode) {
self.init(frame: .zero)
self.text = text
self.value = value
}
@objc private func handleValueChanged() {
value = Mode(rawValue: segmentedControl.selectedSegmentIndex)!
handleChange?(value)
}
}

View File

@@ -1,11 +0,0 @@
//
// Alderis.h
// Alderis
//
// Created by Adam Demasi on 16/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
@import UIKit;
#import "AlderisSDKCompatibility.h"

View File

@@ -1,21 +0,0 @@
//
// AlderisSDKCompatibility.h
// Alderis
//
// Created by Adam Demasi on 3/10/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
@import UIKit;
#ifndef __IPHONE_14_0
// Allows building with the iOS 13 SDK while retaining iOS 14 compatibility.
@interface UIControl ()
- (void)addAction:(UIAction *)action forControlEvents:(UIControlEvents)controlEvents NS_SWIFT_NAME(addAction(_:for:)) API_AVAILABLE(ios(14.0));
- (void)removeAction:(UIAction *)action forControlEvents:(UIControlEvents)controlEvents NS_SWIFT_NAME(removeAction(_:for:)) API_AVAILABLE(ios(14.0));
- (void)removeActionForIdentifier:(UIActionIdentifier)actionIdentifier forControlEvents:(UIControlEvents)controlEvents NS_SWIFT_NAME(removeAction(identifiedBy:for:)) API_AVAILABLE(ios(14.0));
@end
#endif

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "sun.max.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "sun.max@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "sun.max@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "sun.min.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "sun.min@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "sun.min@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 909 B

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "checkmark.circle.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "checkmark.circle.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "checkmark.circle.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "sparkles.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "sparkles@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "sparkles@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "xmark.circle.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "xmark.circle.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "xmark.circle.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "circle.righthalf.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "circle.righthalf.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "circle.righthalf.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "slider.horizontal.3.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "slider.horizontal.3@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "slider.horizontal.3@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "slider.horizontal.below.rectangle.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "slider.horizontal.below.rectangle@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "slider.horizontal.below.rectangle@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "square.grid.4x3.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "square.grid.4x3.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "square.grid.4x3.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

View File

@@ -1,135 +0,0 @@
//
// Assets.swift
// Alderis
//
// Created by Adam Demasi on 27/9/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal struct Assets {
internal enum SymbolScale: Int {
case `default` = -1
case unspecified, small, medium, large
@available(iOS 13, *)
var uiImageSymbolScale: UIImage.SymbolScale { UIImage.SymbolScale(rawValue: rawValue)! }
}
private static let bundle: Bundle = {
let myBundle = Bundle(for: ColorPickerViewController.self)
if let resourcesURL = myBundle.url(forResource: "Alderis", withExtension: "bundle"),
let resourcesBundle = Bundle(url: resourcesURL) {
return resourcesBundle
}
return myBundle
}()
private static let uikitBundle = Bundle(for: UIView.self)
// MARK: - Localization
static func uikitLocalize(_ key: String) -> String {
uikitBundle.localizedString(forKey: key, value: nil, table: nil)
}
// MARK: - Images
static func systemImage(named name: String, font: UIFont? = nil, scale: SymbolScale = .default) -> UIImage? {
if #available(iOS 13, *) {
var configuration: UIImage.SymbolConfiguration?
if let font = font {
configuration = UIImage.SymbolConfiguration(font: font, scale: scale.uiImageSymbolScale)
}
return UIImage(systemName: name, withConfiguration: configuration)
}
return UIImage(named: name, in: bundle, compatibleWith: nil)
}
// MARK: - Fonts
static func niceMonospaceDigitFont(ofSize size: CGFloat) -> UIFont {
// Take the monospace digit font and enable stylistic alternative 6, which provides a
// high-legibility, monospace-looking style of the system font.
let font = UIFont.monospacedDigitSystemFont(ofSize: size, weight: .regular)
let fontDescriptor = font.fontDescriptor.addingAttributes([
.featureSettings: [
[
.alderisFeature: kStylisticAlternativesType,
.alderisSelector: kStylisticAltSixOnSelector
]
] as [[UIFontDescriptor.FeatureKey: Int]]
])
return UIFont(descriptor: fontDescriptor, size: 0)
}
// MARK: - Colors
private static func color(userInterfaceStyles colors: [UIUserInterfaceStyle: UIColor], fallback: UIUserInterfaceStyle = .light) -> UIColor {
if #available(iOS 13, *) {
return UIColor { colors[$0.userInterfaceStyle] ?? colors[fallback] ?? colors.values.first! }
}
return colors[fallback] ?? colors.values.first!
}
static let backdropColor = UIColor(white: 0, alpha: 0.2)
static let separatorColor = UIColor(white: 1, alpha: 0.15)
static let labelColor: UIColor = {
if #available(iOS 13, *) {
return .label
}
return .black
}()
static let secondaryLabelColor: UIColor = {
if #available(iOS 13, *) {
return .secondaryLabel
}
return UIColor(white: 60 / 255, alpha: 0.6)
}()
static let borderColor: UIColor = {
if #available(iOS 13, *) {
return .separator
}
return UIColor(white: 1, alpha: 0.35)
}()
@available(iOS 13, *)
static let macTabBarSelectionColor = color(userInterfaceStyles: [
.light: .black,
.dark: .label
])
static let red = UIColor.systemRed
// .systemGreen adjusted to be more consistent / easier to read
static let green = color(userInterfaceStyles: [
.light: UIColor(red: 15 / 255, green: 189 / 255, blue: 59 / 255, alpha: 1),
// swiftlint:disable:next colon
.dark: UIColor(red: 41 / 255, green: 179 / 255, blue: 76 / 255, alpha: 1)
])
static let checkerboardPatternColor = color(userInterfaceStyles: [
.light: renderCheckerboardPattern(colors: (UIColor(white: 200 / 255, alpha: 1),
UIColor(white: 255 / 255, alpha: 1))),
// swiftlint:disable:next colon
.dark: renderCheckerboardPattern(colors: (UIColor(white: 140 / 255, alpha: 1),
UIColor(white: 186 / 255, alpha: 1)))
])
private static func renderCheckerboardPattern(colors: (dark: UIColor, light: UIColor)) -> UIColor {
let size = 11
let image = UIGraphicsImageRenderer(size: CGSize(width: size * 2, height: size * 2)).image { context in
colors.dark.setFill()
context.fill(CGRect(x: 0, y: 0, width: size * 2, height: size * 2))
colors.light.setFill()
context.fill(CGRect(x: size, y: 0, width: size, height: size))
context.fill(CGRect(x: 0, y: size, width: size, height: size))
}
return UIColor(patternImage: image)
}
}

View File

@@ -1,48 +0,0 @@
//
// BottomSheetTransition.swift
// Alderis
//
// Created by Adam Demasi on 20/9/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class BottomSheetTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return BottomSheetTransition(direction: true)
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return BottomSheetTransition(direction: false)
}
}
internal class BottomSheetTransition: NSObject, UIViewControllerAnimatedTransitioning {
// Opening: true
// Closing: false
let direction: Bool
init(direction: Bool) {
self.direction = direction
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
0.4
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
if direction {
let to = transitionContext.viewController(forKey: .to)!
transitionContext.containerView.addSubview(to.view)
}
Timer.scheduledTimer(withTimeInterval: transitionDuration(using: transitionContext), repeats: false) { _ in
transitionContext.completeTransition(true)
}
}
}

View File

@@ -1,342 +0,0 @@
//
// Color.swift
// Alderis
//
// Created by Adam Demasi on 15/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal struct Color: Equatable, Hashable {
static let black = Color(white: 0, alpha: 1)
static let white = Color(white: 1, alpha: 1)
var red: CGFloat = 0 {
didSet {
self = Color(red: red, green: green, blue: blue, alpha: alpha)
}
}
var green: CGFloat = 0 {
didSet {
self = Color(red: red, green: green, blue: blue, alpha: alpha)
}
}
var blue: CGFloat = 0 {
didSet {
self = Color(red: red, green: green, blue: blue, alpha: alpha)
}
}
var hue: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
}
}
var saturation: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
}
}
var brightness: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
}
}
var hslSaturation: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: hslSaturation, lightness: lightness, alpha: alpha)
}
}
var lightness: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: hslSaturation, lightness: lightness, alpha: alpha)
}
}
var white: CGFloat = 0 {
didSet {
self = Color(white: white, alpha: alpha)
}
}
var alpha: CGFloat = 0
static func == (lhs: Color, rhs: Color) -> Bool {
lhs.red == rhs.red &&
lhs.green == rhs.green &&
lhs.blue == rhs.blue &&
lhs.alpha == rhs.alpha
}
func hash(into hasher: inout Hasher) {
hasher.combine(red)
hasher.combine(green)
hasher.combine(blue)
hasher.combine(alpha)
}
var uiColor: UIColor { .init(red: red, green: green, blue: blue, alpha: alpha) }
init(uiColor: UIColor) {
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil)
self.white = brightness
(self.hslSaturation, self.lightness) = hslValue
}
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
self.red = red
self.green = green
self.blue = blue
self.alpha = alpha
let uiColor = UIColor(red: red, green: green, blue: blue, alpha: alpha)
uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil)
self.white = brightness
(self.hslSaturation, self.lightness) = hslValue
}
init(white: CGFloat, alpha: CGFloat) {
self.init(red: white, green: white, blue: white, alpha: alpha)
}
init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) {
self.hue = hue
self.saturation = saturation
self.brightness = brightness
self.white = brightness
self.alpha = alpha
let uiColor = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
uiColor.getRed(&red, green: &green, blue: &blue, alpha: nil)
(self.hslSaturation, self.lightness) = hslValue
}
init(hue: CGFloat, saturation: CGFloat, lightness: CGFloat, alpha: CGFloat) {
self.hue = hue
self.hslSaturation = saturation
self.lightness = lightness
self.alpha = alpha
(self.saturation, self.brightness) = hsbValue
let uiColor = UIColor(hue: hue, saturation: self.saturation, brightness: self.brightness, alpha: alpha)
uiColor.getRed(&red, green: &green, blue: &blue, alpha: nil)
self.white = brightness
}
}
extension Color {
static var brightnessThreshold: CGFloat {
// Accessibility enabled: conforms to WCAG 2.1 AAA
// Accessibility disabled: conforms to WCAG 2.1 AA
UIAccessibility.isDarkerSystemColorsEnabled ? 7 : 4.5
}
var relativeLuminanceValues: (red: CGFloat, green: CGFloat, blue: CGFloat) {
// https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
let values = [red, green, blue]
.map { $0 <= 0.03928 ? $0 / 12.92 : pow((($0 + 0.055) / 1.055), 2.4) }
return (values[0], values[1], values[2])
}
var relativeLuminance: CGFloat {
// https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
let (r, g, b) = relativeLuminanceValues
return (r * 0.2126) + (g * 0.7152) + (b * 0.0722)
}
func perceivedBrightness(onBackgroundColor background: Color) -> CGFloat {
// https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio - between 0-21
let a = relativeLuminance + 0.05
let b = background.relativeLuminance + 0.05
return a > b ? a / b : b / a
}
var isDark: Bool { perceivedBrightness(onBackgroundColor: .white) > Self.brightnessThreshold && alpha > 0.5 }
}
extension Color {
struct HexOptions: OptionSet {
let rawValue: Int
static let allowShorthand = Self(rawValue: 1 << 0)
static let forceAlpha = Self(rawValue: 1 << 1)
}
// if the character in `value` is repeated, `repeatedValue` is a single copy of that character. If
// `value` consists of two unique characters, `repeatedValue` is nil
// e.g. valid return values are `("AA", "A")` and `("AB", nil)`
private func hex(_ val: CGFloat) -> (value: String, repeatedValue: Character?) {
let byte = Int(val * 255) & 0xFF
let isRepeated = (byte & 0xF) == (byte >> 4)
let value = String(format: "%02X", byte)
return (value, isRepeated ? value.first : nil)
}
func hexString(with options: HexOptions = []) -> String {
let (r, rRep) = hex(red)
let (g, gRep) = hex(green)
let (b, bRep) = hex(blue)
let (a, aRep) = hex(alpha)
let showAlpha = options.contains(.forceAlpha) || alpha != 1
if options.contains(.allowShorthand),
let rRep = rRep, let gRep = gRep, let bRep = bRep, let aRep = aRep {
return "#\(rRep)\(gRep)\(bRep)\(showAlpha ? "\(aRep)" : "")"
} else {
return "#\(r)\(g)\(b)\(showAlpha ? a : "")"
}
}
var hexString: String { hexString() }
var hslValue: (saturation: CGFloat, lightness: CGFloat) {
let lightness = brightness - (brightness * (saturation / 2))
var saturation = min(lightness, 1 - lightness)
saturation = saturation == 0 ? 0 : (brightness - lightness) / saturation
return (saturation, lightness)
}
var hsbValue: (saturation: CGFloat, brightness: CGFloat) {
let brightness = hslSaturation * min(lightness, 1 - lightness) + lightness
let saturation = brightness == 0 ? 0 : 2 - 2 * lightness / brightness
return (saturation, brightness)
}
private func cssString(function: String, params: [String?]) -> String {
let filteredParams = params.compactMap { $0 }
return "\(function)\(filteredParams.count == 4 ? "a" : "")(\(filteredParams.joined(separator: ", ")))"
}
var rgbString: String {
cssString(function: "rgb", params: [
"\(Int(red * 255))",
"\(Int(green * 255))",
"\(Int(blue * 255))",
alpha == 1 ? nil : String(format: "%.2f", alpha)
])
}
var hslString: String {
cssString(function: "hsl", params: [
"\(Int(hue * 360))",
"\(Int(hslSaturation * 100))%",
"\(Int(lightness * 100))%",
alpha == 1 ? nil : String(format: "%.2f", alpha)
])
}
var objcString: String {
red == green && green == blue
? String(format: "[UIColor colorWithWhite:%.3f alpha:%.2f]", white, alpha)
: String(format: "[UIColor colorWithRed:%.3f green:%.3f blue:%.3f alpha:%.2f]", red, green, blue, alpha)
}
var swiftString: String {
red == green && green == blue
? String(format: "UIColor(white: %.3f, alpha: %.3f", white, alpha)
// swiftlint:disable:next color_init
: String(format: "UIColor(red: %.3f, green: %.3f, blue: %.3f, alpha: %.2f)", red, green, blue, alpha)
}
}
extension Color {
struct Component {
let keyPath: WritableKeyPath<Color, CGFloat>
let limit: CGFloat
let title: String
private let sliderTintColorForColor: (Color) -> [Color]
init(
keyPath: WritableKeyPath<Color, CGFloat>,
limit: CGFloat,
title: String,
sliderTintColorForColor: @escaping (Color) -> [Color]
) {
self.keyPath = keyPath
self.limit = limit
self.title = title
self.sliderTintColorForColor = sliderTintColorForColor
}
init(
keyPath: WritableKeyPath<Color, CGFloat>,
limit: CGFloat,
title: String,
sliderTint: [Color]
) {
self.keyPath = keyPath
self.limit = limit
self.title = title
self.sliderTintColorForColor = { _ in sliderTint }
}
func sliderTintColor(for color: Color) -> [Color] {
sliderTintColorForColor(color)
}
static let red: Component = .init(keyPath: \.red, limit: 255, title: "Red") { color in
[
Color(red: 0, green: color.green, blue: color.blue, alpha: 1),
Color(red: 1, green: color.green, blue: color.blue, alpha: 1)
]
}
static let green: Component = .init(keyPath: \.green, limit: 255, title: "Green") { color in
[
Color(red: color.red, green: 0, blue: color.blue, alpha: 1),
Color(red: color.red, green: 1, blue: color.blue, alpha: 1)
]
}
static let blue: Component = .init(keyPath: \.blue, limit: 255, title: "Blue") { color in
[
Color(red: color.red, green: color.green, blue: 0, alpha: 1),
Color(red: color.red, green: color.green, blue: 1, alpha: 1)
]
}
static let hue: Component = .init(keyPath: \.hue, limit: 360, title: "Hue") { color in
Array(0...8).map { Color(hue: CGFloat($0) * 45 / 360, saturation: color.saturation, brightness: color.brightness, alpha: 1) }
}
static let saturation: Component = .init(keyPath: \.saturation, limit: 100, title: "Satur.") { color in
[
.white,
Color(hue: color.hue, saturation: 1, brightness: color.brightness, alpha: 1)
]
}
static let brightness: Component = .init(keyPath: \.brightness, limit: 100, title: "Bright") { color in
[
.black,
Color(hue: color.hue, saturation: color.saturation, brightness: 1, alpha: 1)
]
}
static let hslSaturation: Component = .init(keyPath: \.hslSaturation, limit: 100, title: "Satur.") { color in
[
Color(hue: color.hue, saturation: 0, lightness: color.lightness, alpha: 1),
Color(hue: color.hue, saturation: 1, lightness: color.lightness, alpha: 1)
]
}
static let lightness: Component = .init(keyPath: \.lightness, limit: 100, title: "Light") { color in
[
.black,
Color(hue: color.hue, saturation: color.hslSaturation, lightness: 0.5, alpha: 1),
.white
]
}
static let white: Component = .init(keyPath: \.white, limit: 255, title: "White") { _ in
[
.black,
.white
]
}
static let alpha: Component = .init(keyPath: \.alpha, limit: 100, title: "Alpha") { color in
[
Color(red: color.red, green: color.green, blue: color.blue, alpha: 0),
Color(red: color.red, green: color.green, blue: color.blue, alpha: 1)
]
}
}
}

View File

@@ -1,218 +0,0 @@
//
// ColorPickerAccessibilityViewController.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerAccessibilityViewController: ColorPickerTabViewController {
static let title = "Contrast Checker"
static let imageName = "circle.righthalf.fill"
private static let percentFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .percent
return formatter
}()
private var backgroundMode: AccessibilityContrastSelector.Mode = .white {
didSet { colorDidChange() }
}
private var foregroundMode: AccessibilityContrastSelector.Mode = .color {
didSet { colorDidChange() }
}
private var scrollView: UIScrollView!
private var demoContainerView: UIView!
private var demoLabels: [UIView]!
private var contrastStackView: UIStackView!
private var contrastRatioLabel: UILabel!
private var aaComplianceLabel: AccessibilityComplianceLabel!
private var aaaComplianceLabel: AccessibilityComplianceLabel!
private var backgroundSelector: AccessibilityContrastSelector!
private var foregroundSelector: AccessibilityContrastSelector!
override func viewDidLoad() {
super.viewDidLoad()
// Catalyst in iPad UI mode scales all UI down to 77%, so we cancel out the scaling (as well as
// we possibly can, given scaling down is throwing away quality) for the demo labels.
let scaleFactor: CGFloat = isCatalystPad ? 1 / 0.77 : 1
let demoTitleLabel = UILabel()
demoTitleLabel.translatesAutoresizingMaskIntoConstraints = false
demoTitleLabel.font = .systemFont(ofSize: 18 * scaleFactor, weight: .semibold)
demoTitleLabel.text = "Size 18 • Contrast Checker"
let demoImageView = UIImageView(image: Assets.systemImage(named: "sparkles", font: demoTitleLabel.font, scale: .small))
demoImageView.translatesAutoresizingMaskIntoConstraints = false
let titleStackView = UIStackView(arrangedSubviews: [demoImageView, demoTitleLabel])
titleStackView.translatesAutoresizingMaskIntoConstraints = false
titleStackView.spacing = UIFloat(6)
titleStackView.alignment = .center
let demoSubtitleLabel = UILabel()
demoSubtitleLabel.translatesAutoresizingMaskIntoConstraints = false
demoSubtitleLabel.font = .systemFont(ofSize: 14 * scaleFactor, weight: .medium)
demoSubtitleLabel.text = "Size 14 • Contrast ratios are a measure of how easily text and images can be read, especially by people with lower vision."
demoSubtitleLabel.numberOfLines = 0
let demoTextLabel = TextViewLabel()
demoTextLabel.translatesAutoresizingMaskIntoConstraints = false
demoTextLabel.linkTextAttributes = [
.underlineStyle: NSUnderlineStyle.single.rawValue
]
let explainerText = "Size 12 • Learn more about minimum (AA) and enhanced (AAA) contrast."
let attributedString = NSMutableAttributedString(string: explainerText,
attributes: [
.font: UIFont.systemFont(ofSize: 12 * scaleFactor, weight: .regular)
])
attributedString.addAttribute(.link,
value: URL(string: "https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum")!,
range: (attributedString.string as NSString).range(of: "minimum (AA)"))
attributedString.addAttribute(.link,
value: URL(string: "https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced")!,
range: (attributedString.string as NSString).range(of: "enhanced (AAA)"))
demoTextLabel.attributedText = attributedString
demoLabels = [demoTitleLabel, demoSubtitleLabel, demoTextLabel]
let demoStackView = UIStackView(arrangedSubviews: [titleStackView, demoSubtitleLabel, demoTextLabel])
demoStackView.translatesAutoresizingMaskIntoConstraints = false
demoStackView.axis = .vertical
demoStackView.alignment = .leading
demoStackView.spacing = UIFloat(8)
demoContainerView = UIView()
demoContainerView.translatesAutoresizingMaskIntoConstraints = false
demoContainerView.layer.cornerRadius = 12
if #available(iOS 13, *) {
demoContainerView.layer.cornerCurve = .continuous
}
demoContainerView.addSubview(demoStackView)
contrastRatioLabel = UILabel()
contrastRatioLabel.translatesAutoresizingMaskIntoConstraints = false
contrastRatioLabel.font = .systemFont(ofSize: UIFloat(16), weight: .medium)
aaComplianceLabel = AccessibilityComplianceLabel(text: "AA")
aaaComplianceLabel = AccessibilityComplianceLabel(text: "AAA")
let complianceStackView = UIStackView(arrangedSubviews: [UIView(), aaComplianceLabel, aaaComplianceLabel])
complianceStackView.translatesAutoresizingMaskIntoConstraints = false
complianceStackView.spacing = UIFloat(12)
contrastStackView = UIStackView(arrangedSubviews: [contrastRatioLabel, complianceStackView])
contrastStackView.translatesAutoresizingMaskIntoConstraints = false
contrastStackView.spacing = UIFloat(8)
backgroundSelector = AccessibilityContrastSelector(text: "Background", value: backgroundMode)
backgroundSelector.handleChange = { self.backgroundMode = $0 }
foregroundSelector = AccessibilityContrastSelector(text: "Foreground", value: foregroundMode)
foregroundSelector.handleChange = { self.foregroundMode = $0 }
scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.alwaysBounceVertical = false
view.addSubview(scrollView)
let rootStackView = UIStackView(arrangedSubviews: [demoContainerView, UIView(), contrastStackView, backgroundSelector, foregroundSelector, UIView()])
rootStackView.translatesAutoresizingMaskIntoConstraints = false
rootStackView.axis = .vertical
rootStackView.alignment = .fill
rootStackView.distribution = .fill
rootStackView.spacing = UIFloat(10)
scrollView.addSubview(rootStackView)
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
rootStackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: UIFloat(15)),
rootStackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: UIFloat(-15)),
rootStackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: UIFloat(15)),
rootStackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: UIFloat(-15)),
rootStackView.heightAnchor.constraint(equalTo: scrollView.contentLayoutGuide.heightAnchor, constant: UIFloat(-30)),
scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
scrollView.contentLayoutGuide.heightAnchor.constraint(greaterThanOrEqualTo: scrollView.heightAnchor),
demoStackView.topAnchor.constraint(equalTo: demoContainerView.topAnchor, constant: UIFloat(16)),
demoStackView.bottomAnchor.constraint(equalTo: demoContainerView.bottomAnchor, constant: UIFloat(-17)),
demoStackView.leadingAnchor.constraint(equalTo: demoContainerView.leadingAnchor, constant: UIFloat(20)),
demoStackView.trailingAnchor.constraint(equalTo: demoContainerView.trailingAnchor, constant: UIFloat(-20)),
contrastStackView.heightAnchor.constraint(greaterThanOrEqualTo: backgroundSelector.heightAnchor),
contrastStackView.heightAnchor.constraint(greaterThanOrEqualTo: foregroundSelector.heightAnchor)
])
colorDidChange()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
scrollView.flashScrollIndicators()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
contrastStackView.axis = view.frame.size.width > UIFloat(300) ? .horizontal : .vertical
}
override func colorDidChange() {
let backgroundColor = backgroundMode.color(withColor: color)
let foregroundColor = foregroundMode.color(withColor: color)
if backgroundColor == foregroundColor {
// Change one or the other to not be identical
if backgroundMode == foregroundMode {
switch backgroundMode {
case .black, .white: foregroundMode = .color
default: foregroundMode = .white
}
} else {
if foregroundMode == .color {
backgroundMode = backgroundColor == .white ? .black : .white
} else if backgroundMode == .color {
foregroundMode = foregroundColor == .white ? .black : .white
}
}
return
}
backgroundSelector.value = backgroundMode
foregroundSelector.value = foregroundMode
demoContainerView.backgroundColor = backgroundColor.uiColor
demoContainerView.tintColor = foregroundColor.uiColor
for label in demoLabels {
if let label = label as? UILabel {
label.textColor = foregroundColor.uiColor
} else if let label = label as? UITextView,
let attributedString = label.attributedText.mutableCopy() as? NSMutableAttributedString {
attributedString.addAttribute(.foregroundColor,
value: foregroundColor.uiColor,
range: NSRange(location: 0, length: attributedString.string.count))
label.attributedText = attributedString
}
}
let contrastRatio = foregroundColor.perceivedBrightness(onBackgroundColor: backgroundColor)
contrastRatioLabel.text = "Contrast: \(String(format: "%.2f", contrastRatio)) (\(Self.percentFormatter.string(for: contrastRatio / 21)!))"
aaComplianceLabel.isCompliant = contrastRatio > 4.5
aaaComplianceLabel.isCompliant = contrastRatio > 7
}
}

View File

@@ -1,91 +0,0 @@
//
// ColorPickerConfiguration.swift
// Alderis
//
// Created by Adam Demasi on 10/5/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
/// An enumeration of the tabs `ColorPickerViewController` features. Use these enumeration values to
/// set tab-related settings on `ColorPickerConfiguration`.
@objc(HBColorPickerTab)
public enum ColorPickerTab: Int, CaseIterable {
/// Tab 1: A grid of 9 variations of 11 colours, and a grayscale ramp. The first and default tab.
case swatch = 0
/// Tab 2: A color wheel displaying every possible hue and saturation combination. The user can
/// additionally adjust the brightness of the colour using a slider.
case map = 1
/// Tab 3: A set of sliders for red, green, and blue color values, which can be switched to hue,
/// saturation, and brightness. The user can additionally copy or enter a color value expressed
/// using a CSS-style hexadecimal string, and adjust alpha transparency.
case sliders = 2
/// Tab 4: A tab that allows the user to test various configurations of the color, and its
/// conformance to WCAG color contrast.
case accessibility = 3
}
/// ColorPickerConfiguration is used to configure an instance of `ColorPickerViewController`.
@objc(HBColorPickerConfiguration)
open class ColorPickerConfiguration: NSObject {
/// Initialise a configuration object with the required color property configured.
@objc public init(color: UIColor) {
self.color = color
super.init()
}
/// The initial color to use when launching the color picker. Required. If you dont have a value
/// set yet, provide a sensible default.
@objc open var color: UIColor
/// Whether to allow the user to set an alpha transparency value on the color. This controls the
/// visibility of an Alpha slider on the Sliders tab. When set to `false`, alpha values provided
/// via the `color` property, or by the user when entering a hexadecimal value on the Sliders tab,
/// will be discarded.
@objc open var supportsAlpha = true
/// The title to display at the top of the popup. If set to `nil`, no title will be displayed. The
/// default is `nil`.
@objc open var title: String?
/// The initial tab to select when the color picker is presented. The default is
/// `ColorPickerTab.swatch`.
///
/// This value must be found in `visibleTabs`.
///
/// - see: `visibleTabs`
@objc open var initialTab = ColorPickerTab.swatch
/// The tabs the user can select and switch between at the top of the window, if tabs are enabled
/// by `showTabs`.
///
/// - see: `initialTab`
@nonobjc open var visibleTabs: [ColorPickerTab] = [.swatch, .map, .sliders, .accessibility]
/// Maps `visibleTabs` to Objective-C due to Swift limitations. This is an implementation detail.
/// Ignore this and use `visibleTabs` per usual.
@objc(visibleTabs)
open var _visibleTabsObjC: [ColorPickerTab.RawValue] {
get { visibleTabs.map(\.rawValue) }
set { visibleTabs = newValue.map { ColorPickerTab(rawValue: $0)! } }
}
/// Whether to display the tab selection at the top of the popup. The default is `true`. When set
/// to `false`, the user will only be able to access the tab specified in initialTab.
@objc open var showTabs = true
/// When the Smart Invert accessibility feature is enabled, Alderis instructs the system to not
/// invert most of its user interface. This ensures the user can make a more accurate color
/// selection. If this behavior is not desired, you can disable it here.
@objc open var overrideSmartInvert = true
/// Whether the user can end a drag interaction by dropping on the color picker window, allowing
/// them to drag a color from a supporting app. The default is `true`.
@objc open var isDropInteractionEnabled = true
}

View File

@@ -1,51 +0,0 @@
//
// ColorPickerDelegate.swift
// Alderis
//
// Created by Adam Demasi on 16/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
/// Use `ColorPickerDelegate` to handle the users response to `ColorPickerViewController`.
@objc(HBColorPickerDelegate)
public protocol ColorPickerDelegate: NSObjectProtocol {
/// Informs the delegate that the user has selected a color in the color picker. Optional.
///
/// Use this to update your user interface with the new color value, if suitable to your use case.
///
/// You should, at minimum, implement either this method or `colorPicker(_:didAccept:)`. If you
/// dont intend to implement this method, it is expected that you implement
/// `colorPicker(_:didAccept:)`. If you implement this method and the user selects Cancel, this
/// method will be called with the initial color passed in via `ColorPickerConfiguration.color` to
/// undo the selection.
///
/// - parameter colorPicker: The `ColorPickerViewController` instance that triggered the action.
/// - parameter color: The `UIColor` selection the user made.
/// - see: `colorPicker(_:didAccept:)`
@objc(colorPicker:didSelectColor:)
optional func colorPicker(_ colorPicker: ColorPickerViewController, didSelect color: UIColor)
/// Informs the delegate that the user has dismissed the color picker with a positive response,
/// having selected the selected color. Optional.
///
/// You should, at minimum, implement either this method or `colorPicker(_:didSelect:)`.
///
/// - parameter colorPicker: The `ColorPickerViewController` instance that triggered the action.
/// - parameter color: The `UIColor` selection the user made.
/// - see: `colorPicker(_:didSelect:)`
@objc(colorPicker:didAcceptColor:)
optional func colorPicker(_ colorPicker: ColorPickerViewController, didAccept color: UIColor)
/// Informs the delegate that the user has dismissed the color picker with a negative response.
/// Optional.
///
/// You usually do not need to handle this condition.
///
/// - parameter colorPicker: The `ColorPickerViewController` instance that triggered the action.
@objc(colorPickerDidCancel:)
optional func colorPickerDidCancel(_ colorPicker: ColorPickerViewController)
}

View File

@@ -1,445 +0,0 @@
//
// ColorPickerInnerViewController.swift
// Alderis
//
// Created by Adam Demasi on 12/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal extension ColorPickerTab {
var tabClass: ColorPickerTabViewController.Type {
switch self {
case .swatch: return ColorPickerSwatchViewController.self
case .map: return ColorPickerMapViewController.self
case .sliders: return ColorPickerSlidersViewController.self
case .accessibility: return ColorPickerAccessibilityViewController.self
}
}
var index: Int { Self.allCases.firstIndex(of: self)! }
}
internal class ColorPickerInnerViewController: UIViewController {
weak var delegate: ColorPickerDelegate?
let configuration: ColorPickerConfiguration
var color: Color
var tab: ColorPickerTab {
get { configuration.visibleTabs[currentTab] }
set { currentTab = configuration.visibleTabs.firstIndex(of: newValue) ?? 0 }
}
var compatibilityMode = false
private var colorPicker: ColorPickerViewController {
// swiftlint:disable:next force_cast
parent as! ColorPickerViewController
}
init(delegate: ColorPickerDelegate?, configuration: ColorPickerConfiguration) {
self.delegate = delegate
self.configuration = configuration
color = Color(uiColor: configuration.color)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private var currentTab = 0 {
didSet { tabDidChange(oldValue: oldValue) }
}
func setColor(_ color: Color, withSource source: ColorPickerTabViewControllerBase? = nil) {
self.color = color
colorDidChange(withSource: source)
}
private var pageViewController: UIPageViewController!
private var tabs = [ColorPickerTabViewController]()
private var tabsView: UISegmentedControl!
private var titleLabel: UILabel!
private var cancelButton: DialogButton?
private var saveButton: DialogButton?
private var tabsBackgroundView: UIView!
private var buttonsBackgroundView: UIView?
private var heightConstraint: NSLayoutConstraint!
private var backgroundView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
for tabType in configuration.visibleTabs {
let tab = tabType.tabClass.init(tabDelegate: self, configuration: configuration, color: color)
// Force the view to be initialised
tab.loadViewIfNeeded()
tabs.append(tab)
}
if configuration.isDropInteractionEnabled {
view.addInteraction(UIDropInteraction(delegate: self))
}
backgroundView = UIView()
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.addSubview(backgroundView)
let tabsCheckerboardView = UIView()
tabsCheckerboardView.translatesAutoresizingMaskIntoConstraints = false
tabsCheckerboardView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
tabsCheckerboardView.backgroundColor = Assets.checkerboardPatternColor
view.addSubview(tabsCheckerboardView)
tabsBackgroundView = UIView()
tabsBackgroundView.translatesAutoresizingMaskIntoConstraints = false
tabsBackgroundView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.addSubview(tabsBackgroundView)
let topSeparatorView = SeparatorView(direction: .horizontal)
topSeparatorView.translatesAutoresizingMaskIntoConstraints = false
tabsBackgroundView.addSubview(topSeparatorView)
let titleView = UIView()
titleView.translatesAutoresizingMaskIntoConstraints = false
titleView.isHidden = configuration.title == nil || configuration.title!.isEmpty
titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.textAlignment = .center
titleLabel.font = .systemFont(ofSize: UIFloat(17), weight: .semibold)
titleLabel.text = configuration.title
titleView.addSubview(titleLabel)
let tabsContainerView = UIView()
tabsContainerView.translatesAutoresizingMaskIntoConstraints = false
tabsContainerView.isHidden = !configuration.showTabs
tabsView = UISegmentedControl()
tabsView.translatesAutoresizingMaskIntoConstraints = false
tabsView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
tabsView.addTarget(self, action: #selector(segmentControlChanged(_:)), for: .valueChanged)
tabsContainerView.addSubview(tabsView)
if #available(iOS 13, *) {
tabsView.selectedSegmentTintColor = UIColor.white.withAlphaComponent(0.35)
if isCatalystMac {
tabsView.setTitleTextAttributes([ .foregroundColor: Assets.macTabBarSelectionColor ], for: .highlighted)
tabsView.setTitleTextAttributes([ .foregroundColor: Assets.macTabBarSelectionColor ], for: .selected)
}
}
for (i, tab) in tabs.enumerated() {
let tabClass = type(of: tab)
#if swift(>=5.3)
if #available(iOS 14, *) {
tabsView.insertSegment(action: UIAction(title: tabClass.title,
image: tabClass.image,
handler: { _ in }),
at: i,
animated: false)
} else {
tabsView.insertSegment(with: tabClass.image, at: i, animated: false)
}
#else
tabsView.insertSegment(with: tabClass.image, at: i, animated: false)
#endif
}
NSLayoutConstraint.activate([
tabsView.centerXAnchor.constraint(equalTo: tabsContainerView.centerXAnchor),
tabsView.centerYAnchor.constraint(equalTo: tabsContainerView.centerYAnchor),
tabsView.leadingAnchor.constraint(greaterThanOrEqualTo: tabsContainerView.leadingAnchor, constant: 4),
tabsView.trailingAnchor.constraint(lessThanOrEqualTo: tabsContainerView.trailingAnchor, constant: -4)
])
if #available(iOS 13, *) {
} else {
NSLayoutConstraint.activate([
tabsView.heightAnchor.constraint(equalToConstant: 32)
])
for i in 0..<tabsView.numberOfSegments {
tabsView.setWidth(40, forSegmentAt: i)
}
}
let pageViewContainer = UIView()
pageViewContainer.translatesAutoresizingMaskIntoConstraints = false
pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: [:])
pageViewController.view.translatesAutoresizingMaskIntoConstraints = false
pageViewController.willMove(toParent: self)
addChild(pageViewController)
pageViewContainer.addSubview(pageViewController.view)
let mainStackView = UIStackView(arrangedSubviews: [titleView, tabsContainerView, pageViewContainer])
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.axis = .vertical
mainStackView.alignment = .fill
mainStackView.distribution = .fill
view.addSubview(mainStackView)
heightConstraint = pageViewContainer.heightAnchor.constraint(equalToConstant: 0)
let barHeight: CGFloat = UIFloat(48)
let topHeight = (titleView.isHidden ? 0 : barHeight) + (tabsContainerView.isHidden ? 0 : barHeight)
let titleLabelTopOffset: CGFloat = tabsContainerView.isHidden ? 0 : 3
NSLayoutConstraint.activate([
backgroundView.topAnchor.constraint(equalTo: view.topAnchor),
backgroundView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
mainStackView.topAnchor.constraint(equalTo: view.topAnchor),
mainStackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
mainStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mainStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
titleView.heightAnchor.constraint(equalToConstant: barHeight),
tabsContainerView.heightAnchor.constraint(equalToConstant: barHeight),
titleLabel.topAnchor.constraint(equalTo: titleView.topAnchor, constant: titleLabelTopOffset),
titleLabel.bottomAnchor.constraint(equalTo: titleView.bottomAnchor),
titleLabel.leadingAnchor.constraint(equalTo: titleView.leadingAnchor, constant: 4),
titleLabel.trailingAnchor.constraint(equalTo: titleView.trailingAnchor, constant: -4),
tabsBackgroundView.topAnchor.constraint(equalTo: view.topAnchor),
tabsBackgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tabsBackgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tabsBackgroundView.heightAnchor.constraint(equalToConstant: topHeight),
tabsCheckerboardView.topAnchor.constraint(equalTo: tabsBackgroundView.topAnchor),
tabsCheckerboardView.bottomAnchor.constraint(equalTo: tabsBackgroundView.bottomAnchor),
tabsCheckerboardView.leadingAnchor.constraint(equalTo: tabsBackgroundView.leadingAnchor),
tabsCheckerboardView.trailingAnchor.constraint(equalTo: tabsBackgroundView.trailingAnchor),
topSeparatorView.leadingAnchor.constraint(equalTo: tabsBackgroundView.leadingAnchor),
topSeparatorView.trailingAnchor.constraint(equalTo: tabsBackgroundView.trailingAnchor),
topSeparatorView.bottomAnchor.constraint(equalTo: tabsBackgroundView.bottomAnchor),
pageViewController.view.topAnchor.constraint(equalTo: pageViewContainer.topAnchor),
pageViewController.view.bottomAnchor.constraint(equalTo: pageViewContainer.bottomAnchor),
pageViewController.view.leadingAnchor.constraint(equalTo: pageViewContainer.leadingAnchor),
pageViewController.view.trailingAnchor.constraint(equalTo: pageViewContainer.trailingAnchor),
heightConstraint
])
if !isCatalystMac {
let buttonsCheckerboardView = UIView()
buttonsCheckerboardView.translatesAutoresizingMaskIntoConstraints = false
buttonsCheckerboardView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
buttonsCheckerboardView.backgroundColor = Assets.checkerboardPatternColor
view.insertSubview(buttonsCheckerboardView, aboveSubview: tabsBackgroundView)
let buttonsBackgroundView = UIView()
buttonsBackgroundView.translatesAutoresizingMaskIntoConstraints = false
buttonsBackgroundView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.insertSubview(buttonsBackgroundView, aboveSubview: buttonsCheckerboardView)
self.buttonsBackgroundView = buttonsBackgroundView
let bottomSeparatorView = SeparatorView(direction: .horizontal)
bottomSeparatorView.translatesAutoresizingMaskIntoConstraints = false
buttonsBackgroundView.addSubview(bottomSeparatorView)
let cancelButton = DialogButton()
cancelButton.translatesAutoresizingMaskIntoConstraints = false
cancelButton.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
cancelButton.titleLabel!.font = .systemFont(ofSize: 17, weight: .regular)
cancelButton.setTitle(Assets.uikitLocalize("Cancel"), for: .normal)
cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
self.cancelButton = cancelButton
let saveButton = DialogButton()
saveButton.translatesAutoresizingMaskIntoConstraints = false
saveButton.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
saveButton.titleLabel!.font = .systemFont(ofSize: 17, weight: .semibold)
saveButton.setTitle(Assets.uikitLocalize("Done"), for: .normal)
saveButton.addTarget(self, action: #selector(saveTapped), for: .touchUpInside)
self.saveButton = saveButton
let buttonSeparatorView = SeparatorView(direction: .vertical)
buttonSeparatorView.translatesAutoresizingMaskIntoConstraints = false
buttonsBackgroundView.addSubview(buttonSeparatorView)
let buttonsView = UIStackView(arrangedSubviews: [cancelButton, saveButton])
buttonsView.translatesAutoresizingMaskIntoConstraints = false
buttonsView.axis = .horizontal
buttonsView.alignment = .fill
mainStackView.addSubview(buttonsView)
mainStackView.addArrangedSubview(buttonsView)
NSLayoutConstraint.activate([
buttonsView.heightAnchor.constraint(equalToConstant: barHeight),
buttonsBackgroundView.topAnchor.constraint(equalTo: buttonsView.topAnchor),
buttonsBackgroundView.bottomAnchor.constraint(equalTo: buttonsView.bottomAnchor),
buttonsBackgroundView.leadingAnchor.constraint(equalTo: buttonsView.leadingAnchor),
buttonsBackgroundView.trailingAnchor.constraint(equalTo: buttonsView.trailingAnchor),
buttonSeparatorView.heightAnchor.constraint(equalToConstant: barHeight / 2),
buttonSeparatorView.centerXAnchor.constraint(equalTo: buttonsBackgroundView.centerXAnchor),
buttonSeparatorView.centerYAnchor.constraint(equalTo: buttonsBackgroundView.centerYAnchor),
buttonsCheckerboardView.topAnchor.constraint(equalTo: buttonsBackgroundView.topAnchor),
buttonsCheckerboardView.bottomAnchor.constraint(equalTo: buttonsBackgroundView.bottomAnchor),
buttonsCheckerboardView.leadingAnchor.constraint(equalTo: buttonsBackgroundView.leadingAnchor),
buttonsCheckerboardView.trailingAnchor.constraint(equalTo: buttonsBackgroundView.trailingAnchor),
bottomSeparatorView.leadingAnchor.constraint(equalTo: buttonsBackgroundView.leadingAnchor),
bottomSeparatorView.trailingAnchor.constraint(equalTo: buttonsBackgroundView.trailingAnchor),
bottomSeparatorView.topAnchor.constraint(equalTo: buttonsBackgroundView.topAnchor),
cancelButton.widthAnchor.constraint(equalTo: saveButton.widthAnchor)
])
}
colorDidChange()
tab = configuration.initialTab
tabsView?.selectedSegmentIndex = currentTab
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
updateHeightConstraint()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateHeightConstraint()
}
override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
super.preferredContentSizeDidChange(forChildContentContainer: container)
updateHeightConstraint()
}
private func updateHeightConstraint() {
heightConstraint.constant = (view.frame.size.width / 12) * 10
preferredContentSize = view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
}
@objc private func segmentControlChanged(_ sender: UISegmentedControl) {
UIView.animate(withDuration: 0.2) {
self.currentTab = self.tabsView.selectedSegmentIndex
}
}
@objc private func oldTabButtonTapped(_ sender: UIButton) {
UIView.animate(withDuration: 0.2) {
self.currentTab = sender.tag
}
}
@objc private func cancelTapped() {
if !compatibilityMode {
delegate?.colorPicker?(colorPicker, didSelect: configuration.color)
}
delegate?.colorPickerDidCancel?(colorPicker)
dismiss(animated: true)
}
@objc func saveTapped() {
if compatibilityMode {
delegate?.colorPicker?(colorPicker, didSelect: color.uiColor)
} else {
delegate?.colorPicker?(colorPicker, didAccept: color.uiColor)
}
dismiss(animated: true)
}
private func colorDidChange(withSource source: ColorPickerTabViewControllerBase? = nil) {
let uiColor = color.uiColor
if !compatibilityMode {
delegate?.colorPicker?(colorPicker, didSelect: uiColor)
}
let foregroundColor: UIColor = color.isDark ? .white : .black
view.tintColor = uiColor
tabsBackgroundView.backgroundColor = uiColor
buttonsBackgroundView?.backgroundColor = uiColor
titleLabel.textColor = foregroundColor
cancelButton?.setTitleColor(foregroundColor, for: .normal)
saveButton?.setTitleColor(foregroundColor, for: .normal)
cancelButton?.highlightBackgroundColor = foregroundColor.withAlphaComponent(0.25)
saveButton?.highlightBackgroundColor = foregroundColor.withAlphaComponent(0.25)
tabsView.setTitleTextAttributes([ .foregroundColor: foregroundColor ], for: .normal)
if #available(iOS 13, *) {
} else {
tabsView.tintColor = foregroundColor
}
// Even though `shouldBroadcast: false` avoids recursion if we call setColor on the callee tab,
// doing so on ColorPickerSlidersViewController would reset `hexOptions`, leading to a buggy
// typing experience in `hexTextField`
for tab in tabs where tab != source {
tab.setColor(color, shouldBroadcast: false)
}
backgroundView.backgroundColor = uiColor.withAlphaComponent(color.alpha * 0.2)
}
private func tabDidChange(oldValue: Int) {
let stuff = {
let direction: UIPageViewController.NavigationDirection = self.currentTab < oldValue ? .reverse : .forward
self.pageViewController.setViewControllers([self.tabs[self.currentTab]], direction: direction, animated: !isCatalystMac)
self.colorDidChange()
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
}
if isCatalystMac {
UIView.performWithoutAnimation(stuff)
} else {
stuff()
}
}
}
extension ColorPickerInnerViewController: ColorPickerTabDelegate {
func colorPickerTab(_ tab: ColorPickerTabViewControllerBase, didSelect color: Color) {
setColor(color, withSource: tab)
}
}
extension ColorPickerInnerViewController: UIDropInteractionDelegate {
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
return session.items.count == 1 && session.canLoadObjects(ofClass: UIColor.self)
}
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
return UIDropProposal(operation: .copy)
}
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
session.loadObjects(ofClass: UIColor.self) { items in
if let color = items.first as? UIColor {
self.setColor(Color(uiColor: color), withSource: nil)
}
}
}
}
extension ColorPickerInnerViewController: UIPopoverPresentationControllerDelegate {
/// :nodoc:
public func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
saveTapped()
}
}

View File

@@ -1,49 +0,0 @@
//
// ColorPickerMapSlider.swift
// Alderis
//
// Created by Kabir Oberai on 23/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerMapSlider: ColorPickerComponentSlider {
init(minImageName: String, maxImageName: String, component: Color.Component, overrideSmartInvert: Bool) {
super.init(component: component, overrideSmartInvert: overrideSmartInvert)
stackView.alignment = .center
stackView.spacing = UIFloat(13)
let leftImageView = UIImageView(image: Assets.systemImage(named: minImageName))
leftImageView.translatesAutoresizingMaskIntoConstraints = false
leftImageView.contentMode = .center
leftImageView.tintColor = Assets.secondaryLabelColor
stackView.insertArrangedSubview(leftImageView, at: 0)
let rightImageView = UIImageView(image: Assets.systemImage(named: maxImageName))
rightImageView.translatesAutoresizingMaskIntoConstraints = false
rightImageView.contentMode = .center
rightImageView.tintColor = Assets.secondaryLabelColor
stackView.addArrangedSubview(rightImageView)
if #available(iOS 13, *) {
let symbolConfig = UIImage.SymbolConfiguration(font: .systemFont(ofSize: UIFloat(18), weight: .medium), scale: .medium)
leftImageView.preferredSymbolConfiguration = symbolConfig
rightImageView.preferredSymbolConfiguration = symbolConfig
}
NSLayoutConstraint.activate([
leftImageView.widthAnchor.constraint(equalToConstant: UIFloat(22)),
leftImageView.widthAnchor.constraint(equalTo: rightImageView.widthAnchor),
leftImageView.heightAnchor.constraint(equalTo: leftImageView.widthAnchor),
rightImageView.heightAnchor.constraint(equalTo: rightImageView.widthAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@@ -1,79 +0,0 @@
//
// ColorPickerMapViewController.swift
// Alderis
//
// Created by Adam Demasi on 14/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerMapViewController: ColorPickerTabViewController {
static let title = "Color Wheel"
static let imageName = "slider.horizontal.below.rectangle"
private var wheelView: ColorPickerWheelView!
private var sliders = [ColorPickerMapSlider]()
override func viewDidLoad() {
super.viewDidLoad()
wheelView = ColorPickerWheelView(color: color)
wheelView.translatesAutoresizingMaskIntoConstraints = false
wheelView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
wheelView.delegate = self
view.addSubview(wheelView)
sliders = [
ColorPickerMapSlider(
minImageName: "sun.min", maxImageName: "sun.max", component: .brightness,
overrideSmartInvert: configuration.overrideSmartInvert
)
]
sliders.forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
}
let mainStackView = UIStackView(arrangedSubviews: [wheelView] + sliders)
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.axis = .vertical
mainStackView.alignment = .fill
mainStackView.distribution = .fill
view.addSubview(mainStackView)
NSLayoutConstraint.activate([
mainStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: UIFloat(15)),
mainStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: UIFloat(-15)),
mainStackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
mainStackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: UIFloat(-10))
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
colorDidChange()
}
@objc private func sliderChanged(_ slider: ColorPickerMapSlider) {
var color = self.color
slider.apply(to: &color)
self.setColor(color)
}
override func colorDidChange() {
wheelView.color = color
sliders.forEach { $0.setColor(color) }
}
}
extension ColorPickerMapViewController: ColorPickerWheelViewDelegate {
func colorPickerWheelView(didSelectColor color: Color) {
self.setColor(color)
}
}

View File

@@ -1,83 +0,0 @@
//
// ColorPickerNumericSlider.swift
// Alderis
//
// Created by Kabir Oberai on 28/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerNumericSlider: ColorPickerComponentSlider {
private var textField: UITextField!
override init(component: Color.Component, overrideSmartInvert: Bool) {
super.init(component: component, overrideSmartInvert: overrideSmartInvert)
stackView.alignment = .fill
stackView.spacing = UIFloat(8)
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: UIFloat(16), weight: .medium)
label.text = component.title
stackView.insertArrangedSubview(label, at: 0)
textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.delegate = self
textField.returnKeyType = .next
textField.keyboardType = .numberPad
textField.autocapitalizationType = .none
textField.autocorrectionType = .no
textField.spellCheckingType = .no
textField.textAlignment = .right
textField.font = Assets.niceMonospaceDigitFont(ofSize: UIFloat(16))
stackView.addArrangedSubview(textField)
NSLayoutConstraint.activate([
label.widthAnchor.constraint(equalToConstant: UIFloat(50)),
textField.widthAnchor.constraint(equalToConstant: UIFloat(35))
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setColor(_ color: Color) {
super.setColor(color)
textField.text = "\(Int((color[keyPath: component.keyPath] * component.limit).rounded()))"
}
}
extension ColorPickerNumericSlider: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = textField.text!.replacingCharacters(in: Range(range, in: textField.text!)!, with: string)
guard !newString.isEmpty else { return true }
// Numeric only, 0-limit
let badCharacterSet = CharacterSet(charactersIn: "0123456789").inverted
guard newString.rangeOfCharacter(from: badCharacterSet) == nil else {
beep()
return false
}
let limit = component.limit
guard let value = Int(newString), 0...limit ~= CGFloat(value) else {
beep()
return false
}
// Run this after the input is fully processed by enqueuing it onto the run loop
OperationQueue.main.addOperation {
self.value = CGFloat(value) / limit
self.sliderChanged()
}
return true
}
}

View File

@@ -1,206 +0,0 @@
//
// ColorPickerSlider.swift
// Alderis
//
// Created by Kabir Oberai on 28/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerSliderBase: UIControl {
var overrideSmartInvert: Bool {
didSet {
slider.accessibilityIgnoresInvertColors = overrideSmartInvert
}
}
let stackView: UIStackView
let slider: ColorSlider
var value: CGFloat {
get { CGFloat(slider.value) }
set { slider.value = Float(newValue) }
}
init(overrideSmartInvert: Bool) {
self.overrideSmartInvert = overrideSmartInvert
slider = ColorSlider()
slider.translatesAutoresizingMaskIntoConstraints = false
slider.accessibilityIgnoresInvertColors = overrideSmartInvert
stackView = UIStackView(arrangedSubviews: [slider])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.distribution = .fill
super.init(frame: .zero)
slider.addTarget(self, action: #selector(sliderChanged), for: .valueChanged)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
stackView.topAnchor.constraint(equalTo: self.topAnchor),
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc internal func sliderChanged() {
sendActions(for: .valueChanged)
}
}
internal protocol ColorPickerSliderProtocol: ColorPickerSliderBase {
func setColor(_ color: Color)
func apply(to color: inout Color)
}
internal typealias ColorPickerSlider = ColorPickerSliderBase & ColorPickerSliderProtocol
internal class ColorPickerComponentSlider: ColorPickerSlider {
let component: Color.Component
init(component: Color.Component, overrideSmartInvert: Bool) {
self.component = component
super.init(overrideSmartInvert: overrideSmartInvert)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setColor(_ color: Color) {
value = color[keyPath: component.keyPath]
slider.color = color.uiColor
slider.gradientColors = component.sliderTintColor(for: color).map(\.uiColor)
}
func apply(to color: inout Color) {
color[keyPath: component.keyPath] = value
}
}
internal class ColorSlider: UISlider {
private let thumbImage = UIGraphicsImageRenderer(size: CGSize(width: 26, height: 26)).image { _ in }
var gradientColors = [UIColor]() {
didSet { gradientView.gradientLayer.colors = gradientColors.map(\.cgColor) }
}
var color: UIColor? {
get { selectionView?.color }
set { selectionView?.color = newValue }
}
private var checkerboardView: UIView!
private var gradientView: GradientView!
private var selectionView: ColorWell?
private var selectionViewXConstraint: NSLayoutConstraint?
private var valueObserver: NSKeyValueObservation?
override init(frame: CGRect) {
super.init(frame: frame)
#if swift(>=5.5)
var useSliderTrack = !isCatalystMac
if #available(iOS 15, *) {
preferredBehavioralStyle = .pad
useSliderTrack = true
}
#else
let useSliderTrack = true
#endif
if useSliderTrack {
setMinimumTrackImage(UIImage(), for: .normal)
setMaximumTrackImage(UIImage(), for: .normal)
setThumbImage(thumbImage, for: .normal)
}
checkerboardView = UIView()
checkerboardView.translatesAutoresizingMaskIntoConstraints = false
checkerboardView.backgroundColor = Assets.checkerboardPatternColor
checkerboardView.clipsToBounds = true
if #available(iOS 13, *) {
checkerboardView.layer.cornerCurve = .continuous
}
insertSubview(checkerboardView, at: 0)
gradientView = GradientView()
gradientView.translatesAutoresizingMaskIntoConstraints = false
gradientView.gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientView.gradientLayer.endPoint = CGPoint(x: 1, y: 0)
gradientView.gradientLayer.allowsGroupOpacity = false
checkerboardView.addSubview(gradientView)
NSLayoutConstraint.activate([
checkerboardView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: UIFloat(-3)),
checkerboardView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: UIFloat(3)),
checkerboardView.topAnchor.constraint(equalTo: self.topAnchor, constant: -1),
checkerboardView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 1),
gradientView.leadingAnchor.constraint(equalTo: checkerboardView.leadingAnchor),
gradientView.trailingAnchor.constraint(equalTo: checkerboardView.trailingAnchor),
gradientView.topAnchor.constraint(equalTo: checkerboardView.topAnchor),
gradientView.bottomAnchor.constraint(equalTo: checkerboardView.bottomAnchor),
])
if useSliderTrack {
let selectionView = ColorWell()
selectionView.translatesAutoresizingMaskIntoConstraints = false
selectionView.isDragInteractionEnabled = false
selectionView.isDropInteractionEnabled = false
#if swift(>=5.3)
if #available(iOS 14, *) {
selectionView.isContextMenuInteractionEnabled = false
}
#endif
insertSubview(selectionView, aboveSubview: checkerboardView)
self.selectionView = selectionView
selectionViewXConstraint = selectionView.leadingAnchor.constraint(equalTo: checkerboardView.leadingAnchor)
// Remove minimum width constraint configured by ColorWell internally
let selectionWidthConstraint = selectionView.constraints.first { $0.firstAnchor == selectionView.widthAnchor }
selectionWidthConstraint?.isActive = false
NSLayoutConstraint.activate([
selectionViewXConstraint!,
selectionView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
selectionView.widthAnchor.constraint(equalToConstant: UIFloat(24))
])
valueObserver = observe(\.value) { _, _ in self.valueChanged() }
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
checkerboardView.layer.cornerRadius = checkerboardView.frame.size.height / 2
valueChanged()
}
private func valueChanged() {
guard let selectionView = selectionView,
let selectionViewXConstraint = selectionViewXConstraint else {
return
}
let spacing = frame.size.height - selectionView.frame.size.height
selectionViewXConstraint.constant = (spacing / 2) + ((frame.size.width - selectionView.frame.size.width - spacing) * CGFloat(value))
}
}

View File

@@ -1,266 +0,0 @@
//
// ColorPickerSlidersViewController.swift
// Alderis
//
// Created by Adam Demasi on 14/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
import AudioToolbox
internal class ColorPickerSlidersViewController: ColorPickerTabViewController {
static let title = "Sliders"
static let imageName = "slider.horizontal.3"
private enum Mode: CaseIterable {
case rgb, hsl, hsb, white
var title: String {
switch self {
case .rgb: return "RGB"
case .hsl: return "HSL"
case .hsb: return "HSB"
case .white: return "White"
}
}
private var components: [Color.Component] {
switch self {
case .rgb: return [.red, .green, .blue, .alpha]
case .hsl: return [.hue, .hslSaturation, .lightness, .alpha]
case .hsb: return [.hue, .saturation, .brightness, .alpha]
case .white: return [.white, .alpha]
}
}
func makeSliders(overrideSmartInvert: Bool, supportsAlpha: Bool) -> [ColorPickerNumericSlider] {
components.compactMap { component in
if component.keyPath == \.alpha && !supportsAlpha {
return nil
}
return ColorPickerNumericSlider(component: component, overrideSmartInvert: overrideSmartInvert)
}
}
}
private var mode: Mode = .rgb {
didSet { updateMode() }
}
private var segmentedControl: UISegmentedControl!
private var allSliders = [Mode: [ColorPickerNumericSlider]]()
private var sliderStacks = [Mode: UIStackView]()
private let colorWell = ColorWell()
private var hexTextField: UITextField!
private var hexOptions = Color.HexOptions()
private var eggLabel: UILabel!
private var eggString = ""
override func viewDidLoad() {
super.viewDidLoad()
let segmentedControlContainer = UIView()
segmentedControlContainer.translatesAutoresizingMaskIntoConstraints = false
segmentedControl = UISegmentedControl(items: Mode.allCases.map(\.title))
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: #selector(segmentControlChanged(_:)), for: .valueChanged)
segmentedControlContainer.addSubview(segmentedControl)
let topSpacerView = UIView()
topSpacerView.translatesAutoresizingMaskIntoConstraints = false
let mainStackView = UIStackView(arrangedSubviews: [segmentedControlContainer, topSpacerView])
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.axis = .vertical
mainStackView.alignment = .fill
mainStackView.distribution = .fill
mainStackView.spacing = UIFloat(6)
view.addSubview(mainStackView)
for mode in Mode.allCases {
let modeSliders = mode.makeSliders(overrideSmartInvert: configuration.overrideSmartInvert,
supportsAlpha: configuration.supportsAlpha)
for slider in modeSliders {
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
}
allSliders[mode] = modeSliders
let sliderStackView = UIStackView(arrangedSubviews: modeSliders)
sliderStackView.axis = .vertical
sliderStackView.alignment = .fill
sliderStackView.distribution = .fill
sliderStackView.spacing = UIFloat(10)
sliderStacks[mode] = sliderStackView
mainStackView.addArrangedSubview(sliderStackView)
}
colorWell.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
colorWell.isDragInteractionEnabled = true
colorWell.isDropInteractionEnabled = false
hexTextField = UITextField()
hexTextField.translatesAutoresizingMaskIntoConstraints = false
hexTextField.delegate = self
hexTextField.textAlignment = .right
hexTextField.returnKeyType = .done
hexTextField.autocapitalizationType = .none
hexTextField.autocorrectionType = .no
hexTextField.spellCheckingType = .no
hexTextField.font = Assets.niceMonospaceDigitFont(ofSize: UIFloat(16))
hexTextField.setContentHuggingPriority(.required, for: .vertical)
hexTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
eggLabel = UILabel()
eggLabel.translatesAutoresizingMaskIntoConstraints = false
eggLabel.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
eggLabel.font = UIFont.systemFont(ofSize: UIFloat(24), weight: .heavy)
eggLabel.isHidden = true
let bottomSpacerView = UIView()
bottomSpacerView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.addArrangedSubview(bottomSpacerView)
let hexStackView = UIStackView(arrangedSubviews: [colorWell, eggLabel, hexTextField])
hexStackView.translatesAutoresizingMaskIntoConstraints = false
hexStackView.axis = .horizontal
hexStackView.alignment = .fill
hexStackView.distribution = .fill
hexStackView.spacing = UIFloat(10)
mainStackView.addArrangedSubview(hexStackView)
NSLayoutConstraint.activate([
mainStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: UIFloat(15)),
mainStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: UIFloat(-15)),
mainStackView.topAnchor.constraint(equalTo: view.topAnchor, constant: UIFloat(15)),
mainStackView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: UIFloat(-15)),
segmentedControl.topAnchor.constraint(equalTo: segmentedControlContainer.topAnchor),
segmentedControl.bottomAnchor.constraint(equalTo: segmentedControlContainer.bottomAnchor),
segmentedControl.centerXAnchor.constraint(equalTo: segmentedControlContainer.centerXAnchor),
topSpacerView.heightAnchor.constraint(equalToConstant: UIFloat(3)),
bottomSpacerView.heightAnchor.constraint(equalToConstant: UIFloat(3)),
colorWell.widthAnchor.constraint(equalToConstant: UIFloat(32)),
colorWell.heightAnchor.constraint(equalTo: colorWell.widthAnchor)
])
updateMode()
}
@objc func segmentControlChanged(_ sender: UISegmentedControl) {
view.endEditing(true)
mode = Mode.allCases[sender.selectedSegmentIndex]
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
view.endEditing(true)
}
func updateMode() {
for (stackMode, stack) in sliderStacks {
stack.isHidden = stackMode != mode
}
colorDidChange()
}
func setColor(_ color: Color, hexOptions: Color.HexOptions, shouldBroadcast: Bool = true) {
self.hexOptions = hexOptions
super.setColor(color, shouldBroadcast: shouldBroadcast)
}
override func setColor(_ color: Color, shouldBroadcast: Bool = true) {
self.setColor(color, hexOptions: [], shouldBroadcast: shouldBroadcast)
}
@objc func sliderChanged(_ slider: ColorPickerNumericSlider) {
var color = self.color
slider.apply(to: &color)
setColor(color)
}
override func colorDidChange() {
allSliders[mode]?.forEach {
$0.setColor(color)
}
colorWell.color = color.uiColor
hexTextField.text = color.hexString(with: hexOptions)
if #available(iOS 13, *) {
} else {
let foregroundColor: UIColor = color.isDark ? .white : .black
segmentedControl.setTitleTextAttributes([
.foregroundColor: foregroundColor
], for: .selected)
}
}
}
extension ColorPickerSlidersViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
view.endEditing(true)
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = textField.text!.replacingCharacters(in: Range(range, in: textField.text!)!, with: string)
guard !newString.isEmpty else { return true }
// #AAAAAA
eggString = "\(eggString.suffix(3))\(string)"
if eggString.lowercased() == "holo" {
self.setColor(Color(red: 51 / 255, green: 181 / 255, blue: 229 / 255, alpha: 1))
eggLabel.text = "Praise DuARTe"
eggLabel.textColor = color.uiColor
eggLabel.isHidden = false
eggString = ""
return false
}
let canonicalizedString = newString.hasPrefix("#") ? newString.dropFirst() : Substring(newString)
guard canonicalizedString.count <= 8 else {
beep()
return false
}
let badCharacterSet = CharacterSet(charactersIn: "0123456789ABCDEFabcdef").inverted
guard canonicalizedString.rangeOfCharacter(from: badCharacterSet) == nil else {
beep()
return false
}
if canonicalizedString.count != 6 && canonicalizedString.count != 8 {
// User is probably still typing it out. Dont do anything yet.
return true
}
guard var uiColor = UIColor(propertyListValue: "#\(canonicalizedString)") else {
return true
}
if !configuration.supportsAlpha {
// Discard the alpha component.
uiColor = uiColor.withAlphaComponent(1)
}
let color = Color(uiColor: uiColor)
OperationQueue.main.addOperation {
self.setColor(color, hexOptions: canonicalizedString.count == 3 ? .allowShorthand : [])
}
return true
}
}

View File

@@ -1,303 +0,0 @@
//
// ColorPickerSwatchViewController.swift
// Alderis
//
// Created by Adam Demasi on 13/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerSwatchViewController: ColorPickerTabViewController {
private class ColorLayer: CALayer {
let color: Color
init(color: Color) {
self.color = color
super.init()
backgroundColor = color.uiColor.cgColor
}
override init(layer: Any) {
color = Color(white: 1, alpha: 1)
super.init(layer: layer)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
static let title = "Swatch"
static let imageName = "square.grid.4x3.fill"
static let colorSwatch = [
[
Color(hue: 0.000000, saturation: 0.000000, brightness: 1.000000, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.921569, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.839216, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.760784, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.678431, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.600000, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.521569, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.439216, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.360784, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.278431, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.200000, alpha: 1),
Color(hue: 0.000000, saturation: 0.000000, brightness: 0.000000, alpha: 1),
],
[
Color(hue: 0.542793, saturation: 1.000000, brightness: 0.290196, alpha: 1),
Color(hue: 0.612403, saturation: 0.988506, brightness: 0.341176, alpha: 1),
Color(hue: 0.703704, saturation: 0.915255, brightness: 0.231373, alpha: 1),
Color(hue: 0.787878, saturation: 0.901640, brightness: 0.239216, alpha: 1),
Color(hue: 0.937107, saturation: 0.883333, brightness: 0.235294, alpha: 1),
Color(hue: 0.010989, saturation: 0.989130, brightness: 0.360784, alpha: 1),
Color(hue: 0.051852, saturation: 1.000000, brightness: 0.352941, alpha: 1),
Color(hue: 0.096591, saturation: 1.000000, brightness: 0.345098, alpha: 1),
Color(hue: 0.118217, saturation: 1.000000, brightness: 0.337255, alpha: 1),
Color(hue: 0.158497, saturation: 1.000000, brightness: 0.400000, alpha: 1),
Color(hue: 0.179012, saturation: 0.952941, brightness: 0.333333, alpha: 1),
Color(hue: 0.251773, saturation: 0.758064, brightness: 0.243137, alpha: 1),
],
[
Color(hue: 0.539604, saturation: 1.000000, brightness: 0.396078, alpha: 1),
Color(hue: 0.603825, saturation: 0.991870, brightness: 0.482353, alpha: 1),
Color(hue: 0.703704, saturation: 0.878049, brightness: 0.321569, alpha: 1),
Color(hue: 0.789473, saturation: 0.853933, brightness: 0.349020, alpha: 1),
Color(hue: 0.939614, saturation: 0.811765, brightness: 0.333333, alpha: 1),
Color(hue: 0.021629, saturation: 1.000000, brightness: 0.513725, alpha: 1),
Color(hue: 0.055555, saturation: 1.000000, brightness: 0.482353, alpha: 1),
Color(hue: 0.101093, saturation: 1.000000, brightness: 0.478431, alpha: 1),
Color(hue: 0.122222, saturation: 1.000000, brightness: 0.470588, alpha: 1),
Color(hue: 0.158273, saturation: 0.985816, brightness: 0.552941, alpha: 1),
Color(hue: 0.177469, saturation: 0.915254, brightness: 0.462745, alpha: 1),
Color(hue: 0.251366, saturation: 0.701148, brightness: 0.341176, alpha: 1),
],
[
Color(hue: 0.538732, saturation: 0.993007, brightness: 0.560784, alpha: 1),
Color(hue: 0.601578, saturation: 1.000000, brightness: 0.662745, alpha: 1),
Color(hue: 0.719697, saturation: 0.924370, brightness: 0.466667, alpha: 1),
Color(hue: 0.788333, saturation: 0.806452, brightness: 0.486275, alpha: 1),
Color(hue: 0.938596, saturation: 0.785124, brightness: 0.474510, alpha: 1),
Color(hue: 0.023941, saturation: 1.000000, brightness: 0.709804, alpha: 1),
Color(hue: 0.059730, saturation: 1.000000, brightness: 0.678431, alpha: 1),
Color(hue: 0.102564, saturation: 1.000000, brightness: 0.662745, alpha: 1),
Color(hue: 0.123232, saturation: 0.993976, brightness: 0.650980, alpha: 1),
Color(hue: 0.159864, saturation: 1.000000, brightness: 0.768627, alpha: 1),
Color(hue: 0.177704, saturation: 0.915151, brightness: 0.647059, alpha: 1),
Color(hue: 0.255020, saturation: 0.680328, brightness: 0.478431, alpha: 1),
],
[
Color(hue: 0.537037, saturation: 1.000000, brightness: 0.705882, alpha: 1),
Color(hue: 0.599688, saturation: 1.000000, brightness: 0.839216, alpha: 1),
Color(hue: 0.706284, saturation: 0.824324, brightness: 0.580392, alpha: 1),
Color(hue: 0.785333, saturation: 0.791139, brightness: 0.619608, alpha: 1),
Color(hue: 0.938746, saturation: 0.764707, brightness: 0.600000, alpha: 1),
Color(hue: 0.026549, saturation: 1.000000, brightness: 0.886275, alpha: 1),
Color(hue: 0.061927, saturation: 1.000000, brightness: 0.854902, alpha: 1),
Color(hue: 0.103175, saturation: 0.995261, brightness: 0.827451, alpha: 1),
Color(hue: 0.125000, saturation: 0.995215, brightness: 0.819608, alpha: 1),
Color(hue: 0.160544, saturation: 1.000000, brightness: 0.960784, alpha: 1),
Color(hue: 0.179211, saturation: 0.889952, brightness: 0.819608, alpha: 1),
Color(hue: 0.253968, saturation: 0.668789, brightness: 0.615686, alpha: 1),
],
[
Color(hue: 0.542438, saturation: 1.000000, brightness: 0.847059, alpha: 1),
Color(hue: 0.603018, saturation: 1.000000, brightness: 0.996078, alpha: 1),
Color(hue: 0.716435, saturation: 0.808989, brightness: 0.698039, alpha: 1),
Color(hue: 0.792237, saturation: 0.776596, brightness: 0.737255, alpha: 1),
Color(hue: 0.942857, saturation: 0.756756, brightness: 0.725490, alpha: 1),
Color(hue: 0.030627, saturation: 0.917647, brightness: 1.000000, alpha: 1),
Color(hue: 0.069281, saturation: 1.000000, brightness: 1.000000, alpha: 1),
Color(hue: 0.111549, saturation: 0.996078, brightness: 1.000000, alpha: 1),
Color(hue: 0.131093, saturation: 1.000000, brightness: 0.992157, alpha: 1),
Color(hue: 0.164021, saturation: 0.744094, brightness: 0.996078, alpha: 1),
Color(hue: 0.184162, saturation: 0.766949, brightness: 0.925490, alpha: 1),
Color(hue: 0.260163, saturation: 0.657754, brightness: 0.733333, alpha: 1),
],
[
Color(hue: 0.535193, saturation: 0.996032, brightness: 0.988235, alpha: 1),
Color(hue: 0.601190, saturation: 0.771653, brightness: 0.996078, alpha: 1),
Color(hue: 0.707665, saturation: 0.795745, brightness: 0.921569, alpha: 1),
Color(hue: 0.786096, saturation: 0.769547, brightness: 0.952941, alpha: 1),
Color(hue: 0.938597, saturation: 0.743478, brightness: 0.901961, alpha: 1),
Color(hue: 0.017143, saturation: 0.686275, brightness: 1.000000, alpha: 1),
Color(hue: 0.056466, saturation: 0.717647, brightness: 1.000000, alpha: 1),
Color(hue: 0.102094, saturation: 0.751968, brightness: 0.996078, alpha: 1),
Color(hue: 0.122396, saturation: 0.755906, brightness: 0.996078, alpha: 1),
Color(hue: 0.157658, saturation: 0.580392, brightness: 1.000000, alpha: 1),
Color(hue: 0.179952, saturation: 0.577406, brightness: 0.937255, alpha: 1),
Color(hue: 0.254310, saturation: 0.549763, brightness: 0.827451, alpha: 1),
],
[
Color(hue: 0.537255, saturation: 0.674603, brightness: 0.988235, alpha: 1),
Color(hue: 0.605516, saturation: 0.545098, brightness: 1.000000, alpha: 1),
Color(hue: 0.719048, saturation: 0.688976, brightness: 0.996078, alpha: 1),
Color(hue: 0.790419, saturation: 0.657481, brightness: 0.996078, alpha: 1),
Color(hue: 0.940000, saturation: 0.525210, brightness: 0.933333, alpha: 1),
Color(hue: 0.013333, saturation: 0.490196, brightness: 1.000000, alpha: 1),
Color(hue: 0.051282, saturation: 0.509804, brightness: 1.000000, alpha: 1),
Color(hue: 0.098039, saturation: 0.533333, brightness: 1.000000, alpha: 1),
Color(hue: 0.120098, saturation: 0.533333, brightness: 1.000000, alpha: 1),
Color(hue: 0.157321, saturation: 0.419608, brightness: 1.000000, alpha: 1),
Color(hue: 0.180135, saturation: 0.409091, brightness: 0.949020, alpha: 1),
Color(hue: 0.256097, saturation: 0.371041, brightness: 0.866667, alpha: 1),
],
[
Color(hue: 0.540881, saturation: 0.418972, brightness: 0.992157, alpha: 1),
Color(hue: 0.607954, saturation: 0.345098, brightness: 1.000000, alpha: 1),
Color(hue: 0.720760, saturation: 0.448818, brightness: 0.996078, alpha: 1),
Color(hue: 0.790124, saturation: 0.425197, brightness: 0.996078, alpha: 1),
Color(hue: 0.941667, saturation: 0.327869, brightness: 0.956863, alpha: 1),
Color(hue: 0.012500, saturation: 0.313725, brightness: 1.000000, alpha: 1),
Color(hue: 0.051587, saturation: 0.329412, brightness: 1.000000, alpha: 1),
Color(hue: 0.093869, saturation: 0.341176, brightness: 1.000000, alpha: 1),
Color(hue: 0.116279, saturation: 0.338582, brightness: 0.996078, alpha: 1),
Color(hue: 0.157143, saturation: 0.274510, brightness: 1.000000, alpha: 1),
Color(hue: 0.179687, saturation: 0.259109, brightness: 0.968627, alpha: 1),
Color(hue: 0.254902, saturation: 0.219828, brightness: 0.909804, alpha: 1),
],
[
Color(hue: 0.548077, saturation: 0.203922, brightness: 1.000000, alpha: 1),
Color(hue: 0.609848, saturation: 0.172549, brightness: 1.000000, alpha: 1),
Color(hue: 0.716981, saturation: 0.208661, brightness: 0.996078, alpha: 1),
Color(hue: 0.783019, saturation: 0.207843, brightness: 1.000000, alpha: 1),
Color(hue: 0.942983, saturation: 0.152611, brightness: 0.976471, alpha: 1),
Color(hue: 0.012821, saturation: 0.152941, brightness: 1.000000, alpha: 1),
Color(hue: 0.048781, saturation: 0.160784, brightness: 1.000000, alpha: 1),
Color(hue: 0.093023, saturation: 0.168627, brightness: 1.000000, alpha: 1),
Color(hue: 0.115080, saturation: 0.164706, brightness: 1.000000, alpha: 1),
Color(hue: 0.156566, saturation: 0.129921, brightness: 0.996078, alpha: 1),
Color(hue: 0.182796, saturation: 0.123999, brightness: 0.980392, alpha: 1),
Color(hue: 0.262820, saturation: 0.109243, brightness: 0.933333, alpha: 1),
]
]
let colors = ColorPickerSwatchViewController.colorSwatch
private var colorRows = [[ColorLayer]]()
private var colorDict = [String: ColorLayer]()
var containerView: UIView!
var selectionView: UIView!
var containerViewHeightConstraint: NSLayoutConstraint!
var selectionViewWidthConstraint: NSLayoutConstraint!
var selectionViewXConstraint: NSLayoutConstraint!
var selectionViewYConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.addSubview(containerView)
for row in colors {
var colorRow = [ColorLayer]()
for color in row {
let colorLayer = ColorLayer(color: color)
containerView.layer.addSublayer(colorLayer)
colorDict[color.hexString()] = colorLayer
colorRow.append(colorLayer)
}
colorRows.append(colorRow)
}
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(gestureRecognizerFired(_:))))
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(gestureRecognizerFired(_:)))
panGestureRecognizer.maximumNumberOfTouches = 1
view.addGestureRecognizer(panGestureRecognizer)
selectionView = UIView()
selectionView.translatesAutoresizingMaskIntoConstraints = false
selectionView.isUserInteractionEnabled = false
selectionView.layer.borderColor = UIColor.white.cgColor
selectionView.layer.borderWidth = 2
selectionView.layer.shadowOffset = CGSize(width: 0, height: 0)
selectionView.layer.shadowOpacity = 1
selectionView.layer.shadowColor = UIColor(white: 0, alpha: 0.1).cgColor
view.addSubview(selectionView)
containerViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: 0)
selectionViewWidthConstraint = selectionView.widthAnchor.constraint(equalToConstant: UIFloat(20))
let selectionViewBaseXConstraint = selectionView.leftAnchor.constraint(equalTo: view.leftAnchor)
selectionViewBaseXConstraint.priority = .defaultLow
let selectionViewBaseYConstraint = selectionView.topAnchor.constraint(equalTo: view.topAnchor)
selectionViewBaseYConstraint.priority = .defaultLow
selectionViewXConstraint = selectionView.leftAnchor.constraint(equalTo: view.leftAnchor)
selectionViewYConstraint = selectionView.topAnchor.constraint(equalTo: view.topAnchor)
NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
containerView.topAnchor.constraint(equalTo: view.topAnchor),
containerView.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor),
containerViewHeightConstraint,
selectionViewWidthConstraint,
selectionView.heightAnchor.constraint(equalTo: selectionView.widthAnchor),
selectionViewBaseXConstraint,
selectionViewBaseYConstraint,
selectionViewXConstraint,
selectionViewYConstraint
])
colorDidChange()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var x: CGFloat = 0, y: CGFloat = 0
let size = view.frame.size.width / CGFloat(colors[0].count)
for row in colorRows {
x = 0
for item in row {
item.frame = CGRect(x: x * size, y: y * size, width: size, height: size)
x += 1
}
y += 1
}
containerViewHeightConstraint.constant = y * size
selectionViewWidthConstraint.constant = size
UIView.performWithoutAnimation {
colorDidChange()
}
}
@objc private func gestureRecognizerFired(_ sender: UIGestureRecognizer) {
switch sender.state {
case .began, .changed, .ended:
let location = sender.location(in: containerView)
guard let colorView = containerView.layer.hitTest(location) as? ColorLayer else {
return
}
self.setColor(colorView.color)
case .possible, .cancelled, .failed:
break
@unknown default:
break
}
}
func setSelection(to colorLayer: CALayer?) {
let wasHidden = selectionView.isHidden
selectionView.isHidden = colorLayer == nil
selectionViewXConstraint.constant = colorLayer?.frame.origin.x ?? 0
selectionViewYConstraint.constant = colorLayer?.frame.origin.y ?? 0
if wasHidden {
view.layoutIfNeeded()
} else {
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
}
}
override func colorDidChange() {
guard selectionView != nil else { return }
setSelection(to: colorDict[color.hexString()])
}
}

View File

@@ -1,60 +0,0 @@
//
// ColorPickerTabViewController.swift
// Alderis
//
// Created by Kabir Oberai on 23/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal protocol ColorPickerTabDelegate: AnyObject {
func colorPickerTab(_ tab: ColorPickerTabViewControllerBase, didSelect color: Color)
}
internal class ColorPickerTabViewControllerBase: UIViewController {
unowned var tabDelegate: ColorPickerTabDelegate
private(set) var configuration: ColorPickerConfiguration
private(set) var color: Color {
didSet { colorDidChange() }
}
func colorDidChange() {}
func setColor(_ color: Color, shouldBroadcast: Bool = true) {
if self.color == color {
return
}
self.color = color
if shouldBroadcast {
tabDelegate.colorPickerTab(self, didSelect: color)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
required init(tabDelegate: ColorPickerTabDelegate, configuration: ColorPickerConfiguration, color: Color) {
self.tabDelegate = tabDelegate
self.configuration = configuration
self.color = color
super.init(nibName: nil, bundle: nil)
}
}
internal protocol ColorPickerTabViewControllerProtocol: ColorPickerTabViewControllerBase {
static var title: String { get }
static var imageName: String { get }
static var image: UIImage { get }
}
extension ColorPickerTabViewControllerProtocol {
static var image: UIImage { Assets.systemImage(named: imageName, font: .systemFont(ofSize: UIFloat(20), weight: .medium)) ?? UIImage() }
}
internal typealias ColorPickerTabViewController = ColorPickerTabViewControllerBase & ColorPickerTabViewControllerProtocol

View File

@@ -1,385 +0,0 @@
//
// ColorPickerViewController.swift
// Alderis
//
// Created by Adam Demasi on 12/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
/// Provides the Color Picker user interface.
///
/// Present this view controller to display the color picker. Do not push it onto a navigation
/// controller stack. In horizontally and vertically regular size class environments, for instance
/// on iPad and Mac, the picker will be presented as a popover. This means that you must set
/// `sourceView` or other similar properties on the view controllers `popoverPresentationController`
/// before presentation.
///
/// To review examples of `ColorPickerViewController` in use, run `pod try Alderis`.
@objc(HBColorPickerViewController)
open class ColorPickerViewController: UIViewController {
/// Do not rely on this fallback value - always specify a color!
private static let defaultColor = UIColor(white: 0.6, alpha: 1)
/// Initialise an instance of `ColorPickerViewController` with a configuration object.
///
/// Remember to set the `delegate` before presenting the view controller.
@objc public init(configuration: ColorPickerConfiguration) {
self.configuration = configuration
super.init(nibName: nil, bundle: nil)
setUp()
}
/// The delegate that will receive the users selection upon tapping the Done button, or a
/// cancellation upon tapping the Cancel button.
@objc open weak var delegate: ColorPickerDelegate? {
didSet { innerViewController?.delegate = delegate }
}
/// The configuration of the color picker. Use this to set the initially selected color, as well
/// as other behavioral options.
///
/// Making changes to this value or its properties after the color picker interface has been
/// presented may result in undefined behavior.
///
/// - see: `ColorPickerConfiguration`
@objc open var configuration: ColorPickerConfiguration!
/// Deprecated. Set `ColorPickerConfiguration.overrideSmartInvert` instead.
///
/// - see: `ColorPickerConfiguration.overrideSmartInvert`
@available(*, deprecated, message: "Use ColorPickerConfiguration instead")
@objc open var overrideSmartInvert = true
/// Deprecated. Set `ColorPickerConfiguration.color` instead.
///
/// - see: `ColorPickerConfiguration.color`
@available(*, deprecated, message: "Use ColorPickerConfiguration instead")
@objc open var color = ColorPickerViewController.defaultColor
// A width divisible by 12 (the number of items wide in the swatch).
private var finalWidth: CGFloat {
if modalPresentationStyle == .popover {
return UIFloat(336)
} else {
return floor(min(UIFloat(384), view.frame.size.width - 30) / 12) * 12
}
}
private var isFullScreen: Bool { modalPresentationStyle != .popover }
private var innerViewController: ColorPickerInnerViewController!
private var backdropView: UIView!
private var backgroundView: UIVisualEffectView!
private var widthLayoutConstraint: NSLayoutConstraint!
private var bottomLayoutConstraint: NSLayoutConstraint!
private var bottomAnimatingLayoutConstraint: NSLayoutConstraint!
// swiftlint:disable:next weak_delegate
private lazy var _transitioningDelegate = BottomSheetTransitioningDelegate()
private var initialBottomSafeAreaInset: CGFloat?
private var isKeyboardVisible = false
/// :nodoc:
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
self.configuration = nil
super.init(nibName: nil, bundle: nil)
setUp()
}
/// :nodoc:
required public init?(coder: NSCoder) {
self.configuration = nil
super.init(coder: coder)
setUp()
}
private func setUp() {
if traitCollection.horizontalSizeClass == .regular && traitCollection.verticalSizeClass == .regular {
modalPresentationStyle = .popover
} else {
modalPresentationStyle = .overCurrentContext
transitioningDelegate = _transitioningDelegate
}
}
/// :nodoc:
override open func viewDidLoad() {
super.viewDidLoad()
var compatibilityMode = false
if configuration == nil {
let deprecatedAPI: ColorPickerViewControllerDeprecatedMethods = self
// Yes, Swift, I know my code for handling deprecated API usage uses deprecated API 🙄
if deprecatedAPI.color == ColorPickerViewController.defaultColor {
fatalError("Alderis: You need to set a configuration. https://hbang.github.io/Alderis/")
}
NSLog("Alderis: Deprecated configuration API in use. This will be removed in a future release. Migrate to using ColorPickerConfiguration. https://hbang.github.io/Alderis/")
compatibilityMode = true
configuration = ColorPickerConfiguration(color: deprecatedAPI.color)
configuration.overrideSmartInvert = deprecatedAPI.overrideSmartInvert
}
if !configuration.supportsAlpha {
// Force the color to be fully opaque.
configuration.color = configuration.color.withAlphaComponent(1)
}
navigationController?.isNavigationBarHidden = true
view.backgroundColor = .clear
preferredContentSize = .zero
if isFullScreen {
backdropView = UIView()
backdropView.translatesAutoresizingMaskIntoConstraints = false
backdropView.backgroundColor = Assets.backdropColor
backdropView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissGestureFired(_:))))
view.addSubview(backdropView)
}
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(containerView)
if isFullScreen {
let style: UIBlurEffect.Style
if #available(iOS 13, *) {
style = .systemThinMaterial
} else {
style = .light
}
backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: style))
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.clipsToBounds = true
backgroundView.layer.cornerRadius = 13
if #available(iOS 13, *) {
backgroundView.layer.cornerCurve = .continuous
}
containerView.addSubview(backgroundView)
}
innerViewController = ColorPickerInnerViewController(delegate: delegate, configuration: configuration)
innerViewController.compatibilityMode = compatibilityMode
innerViewController.willMove(toParent: self)
addChild(innerViewController)
innerViewController.view.translatesAutoresizingMaskIntoConstraints = false
if isFullScreen {
innerViewController.view.clipsToBounds = true
innerViewController.view.layer.cornerRadius = 13
innerViewController.view.layer.borderWidth = 1
innerViewController.view.layer.borderColor = Assets.borderColor.cgColor
if #available(iOS 13, *) {
innerViewController.view.layer.cornerCurve = .continuous
}
} else {
popoverPresentationController?.delegate = innerViewController
}
containerView.addSubview(innerViewController.view)
widthLayoutConstraint = containerView.widthAnchor.constraint(equalToConstant: finalWidth)
bottomLayoutConstraint = view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 0)
bottomAnimatingLayoutConstraint = view.bottomAnchor.constraint(equalTo: containerView.topAnchor)
NSLayoutConstraint.activate(
[
widthLayoutConstraint,
innerViewController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
innerViewController.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
innerViewController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
innerViewController.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
] +
(isFullScreen ? [
backdropView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
backdropView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
backdropView.topAnchor.constraint(equalTo: view.topAnchor),
backdropView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
backgroundView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
backgroundView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
backgroundView.topAnchor.constraint(equalTo: containerView.topAnchor),
backgroundView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
containerView.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
bottomLayoutConstraint
] : [
containerView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
containerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
containerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
)
}
/// :nodoc:
override open func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
widthLayoutConstraint.constant = finalWidth
if isFullScreen {
innerViewController.view.layer.borderWidth = 1 / (view.window?.screen.scale ?? 1)
}
}
/// :nodoc:
override open func viewSafeAreaInsetsDidChange() {
super.viewSafeAreaInsetsDidChange()
if !isKeyboardVisible {
initialBottomSafeAreaInset = view.safeAreaInsets.bottom
bottomLayoutConstraint.constant = initialBottomSafeAreaInset == 0 ? 15 : 0
}
}
/// :nodoc:
open override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
super.preferredContentSizeDidChange(forChildContentContainer: container)
if !isFullScreen {
preferredContentSize = CGSize(width: finalWidth,
height: innerViewController.preferredContentSize.height)
}
}
/// :nodoc:
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if navigationController != nil && navigationController!.viewControllers.count > 1 {
assertionFailure("Do not push \(String(describing: type(of: self))) onto a navigation controller stack. It must be presented using UIViewController.present(_:animated:completion:).")
}
if animated && isFullScreen {
backdropView.alpha = 0
bottomLayoutConstraint.isActive = false
bottomAnimatingLayoutConstraint.isActive = true
view.layoutIfNeeded()
UIView.animate(withDuration: 0.4,
delay: 0,
usingSpringWithDamping: 2,
initialSpringVelocity: 0.5,
options: [],
animations: {
self.backdropView.alpha = 1
self.bottomLayoutConstraint.isActive = true
self.bottomAnimatingLayoutConstraint.isActive = false
self.view.layoutIfNeeded()
},
completion: nil)
}
}
private let keyboardNotificationNames = [
UIResponder.keyboardWillShowNotification,
UIResponder.keyboardWillHideNotification,
UIResponder.keyboardWillChangeFrameNotification
]
/// :nodoc:
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for name in keyboardNotificationNames {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardFrameWillChange(_:)), name: name, object: nil)
}
}
/// :nodoc:
override open func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
for name in keyboardNotificationNames {
NotificationCenter.default.removeObserver(self, name: name, object: nil)
}
if animated && isFullScreen {
backdropView.alpha = 1
bottomLayoutConstraint.isActive = true
bottomAnimatingLayoutConstraint.isActive = false
view.layoutIfNeeded()
UIView.animate(withDuration: 0.4,
delay: 0,
usingSpringWithDamping: 0.8,
initialSpringVelocity: 0.5,
options: [],
animations: {
self.backdropView.alpha = 0
self.bottomLayoutConstraint.isActive = false
self.bottomAnimatingLayoutConstraint.isActive = true
self.view.layoutIfNeeded()
},
completion: nil)
}
}
/// :nodoc:
override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if isFullScreen {
// CGColor doesnt support dynamic colors, so we need to set this again.
innerViewController.view.layer.borderColor = Assets.borderColor.cgColor
}
}
@objc private func keyboardFrameWillChange(_ notification: Notification) {
if !isFullScreen {
return
}
guard let userInfo = notification.userInfo,
let keyboardEndFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval,
let curve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt
else {
return
}
isKeyboardVisible = notification.name != UIResponder.keyboardWillHideNotification
var options: UIView.AnimationOptions = .beginFromCurrentState
options.insert(.init(rawValue: curve << 16))
UIView.animate(withDuration: duration,
delay: 0,
options: options,
animations: {
let keyboardHeight: CGFloat = (self.isKeyboardVisible ? keyboardEndFrame.size.height : 0)
let keyboardExtraMargin: CGFloat = (self.isKeyboardVisible && self.initialBottomSafeAreaInset != 0 ? 15 : 0)
let bottom = max(keyboardHeight - (self.initialBottomSafeAreaInset ?? 0), 0) + keyboardExtraMargin
self.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: bottom, right: 0)
self.view.layoutIfNeeded()
},
completion: nil)
}
@objc private func dismissGestureFired(_ gestureRecognizer: UITapGestureRecognizer) {
if gestureRecognizer.state == .ended {
if isKeyboardVisible {
view.endEditing(true)
} else {
innerViewController.saveTapped()
dismiss(animated: true, completion: nil)
}
}
}
}
/// :nodoc:
private protocol ColorPickerViewControllerDeprecatedMethods {
var color: UIColor { get }
var overrideSmartInvert: Bool { get }
}
/// :nodoc:
extension ColorPickerViewController: ColorPickerViewControllerDeprecatedMethods {}

View File

@@ -1,242 +0,0 @@
//
// ColorPickerMapView.swift
// Alderis
//
// Created by Adam Demasi on 14/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal protocol ColorPickerWheelViewDelegate: AnyObject {
func colorPickerWheelView(didSelectColor color: Color)
}
internal class ColorPickerWheelView: UIView {
weak var delegate: ColorPickerWheelViewDelegate?
var color: Color {
didSet { updateColor() }
}
private var containerView: UIView!
private var wheelView: ColorPickerWheelInnerView!
private var selectionView: ColorWell!
private var selectionViewXConstraint: NSLayoutConstraint!
private var selectionViewYConstraint: NSLayoutConstraint!
private var selectionViewFingerDownConstraint: NSLayoutConstraint!
private var isFingerDown = false
private let touchDownFeedbackGenerator = UIImpactFeedbackGenerator(style: .medium)
private let touchUpFeedbackGenerator = UIImpactFeedbackGenerator(style: .light)
init(color: Color) {
self.color = color
super.init(frame: .zero)
containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.clipsToBounds = true
addSubview(containerView)
containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(gestureRecognizerFired(_:))))
containerView.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(gestureRecognizerFired(_:))))
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(gestureRecognizerFired(_:)))
panGestureRecognizer.maximumNumberOfTouches = 1
containerView.addGestureRecognizer(panGestureRecognizer)
wheelView = ColorPickerWheelInnerView()
wheelView.translatesAutoresizingMaskIntoConstraints = false
wheelView.handleLayout = { [weak self] in self?.setNeedsLayout() }
containerView.addSubview(wheelView)
selectionView = ColorWell()
selectionView.translatesAutoresizingMaskIntoConstraints = false
selectionView.isDragInteractionEnabled = false
selectionView.isDropInteractionEnabled = false
#if swift(>=5.3)
if #available(iOS 14, *) {
selectionView.isContextMenuInteractionEnabled = false
}
#endif
containerView.addSubview(selectionView)
selectionViewXConstraint = selectionView.leftAnchor.constraint(equalTo: containerView.leftAnchor)
selectionViewYConstraint = selectionView.topAnchor.constraint(equalTo: containerView.topAnchor)
// https://www.youtube.com/watch?v=Qs8kDiOwPBA
selectionViewFingerDownConstraint = selectionView.widthAnchor.constraint(equalToConstant: 56)
let selectionViewNormalConstraint = selectionView.widthAnchor.constraint(equalToConstant: UIFloat(24))
selectionViewNormalConstraint.priority = .defaultHigh
// Remove minimum width constraint configured by ColorWell internally
let selectionWidthConstraint = selectionView.constraints.first { $0.firstAnchor == selectionView.widthAnchor }
selectionWidthConstraint?.isActive = false
NSLayoutConstraint.activate([
containerView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
containerView.topAnchor.constraint(equalTo: self.topAnchor),
containerView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
containerView.widthAnchor.constraint(equalTo: containerView.heightAnchor, constant: UIFloat(30)),
wheelView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: UIFloat(30)),
wheelView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: UIFloat(-30)),
wheelView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: UIFloat(15)),
wheelView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: UIFloat(-15)),
selectionViewXConstraint,
selectionViewYConstraint,
selectionViewNormalConstraint,
selectionView.heightAnchor.constraint(equalTo: selectionView.widthAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
updateSelectionPoint()
}
private func updateColor() {
wheelView.brightness = color.brightness
selectionView.backgroundColor = color.uiColor
updateSelectionPoint()
}
private func updateSelectionPoint() {
let colorPoint = pointForColor(color, in: wheelView.frame.size)
let point = CGPoint(x: wheelView.frame.origin.x + colorPoint.x - (selectionView.frame.size.width / 2),
y: min(
frame.size.height - selectionView.frame.size.height - 1,
max(1, wheelView.frame.origin.y + colorPoint.y - (selectionView.frame.size.height / 2))
))
selectionViewXConstraint.constant = point.x
selectionViewYConstraint.constant = point.y
}
private func colorAt(position: CGPoint, in size: CGSize) -> Color {
let point = CGPoint(x: (size.width / 2) - position.x,
y: (size.height / 2) - position.y)
let h = 180 + round(atan2(point.y, point.x) * (180 / .pi))
let handleRange = size.width / 2
let handleDistance = min(sqrt(point.x * point.x + point.y * point.y), handleRange)
let s = round(100 / handleRange * handleDistance)
return Color(hue: h / 360, saturation: s / 100, brightness: color.brightness, alpha: 1)
}
private func pointForColor(_ color: Color, in size: CGSize) -> CGPoint {
let handleRange = size.width / 2
let handleAngle = (color.hue * 360) * (.pi / 180)
let handleDistance = color.saturation * handleRange
return CGPoint(x: (size.width / 2) + handleDistance * cos(handleAngle),
y: (size.height / 2) + handleDistance * sin(handleAngle))
}
@objc private func gestureRecognizerFired(_ sender: UIGestureRecognizer) {
switch sender.state {
case .began, .changed, .ended:
var location = sender.location(in: containerView)
location.x -= wheelView.frame.origin.x
location.y -= wheelView.frame.origin.y
color = colorAt(position: location, in: wheelView.frame.size)
delegate?.colorPickerWheelView(didSelectColor: color)
case .possible, .cancelled, .failed:
break
@unknown default:
break
}
if sender is UITapGestureRecognizer {
return
}
switch sender.state {
case .began, .ended, .cancelled:
isFingerDown = sender.state == .began
selectionViewFingerDownConstraint.isActive = isFingerDown && !isCatalyst
updateSelectionPoint()
UIView.animate(withDuration: 0.2, animations: {
self.containerView.layoutIfNeeded()
self.updateSelectionPoint()
}, completion: { _ in
self.updateSelectionPoint()
})
if sender.state == .began {
touchDownFeedbackGenerator.impactOccurred()
} else {
touchUpFeedbackGenerator.impactOccurred()
}
case .possible, .changed, .failed:
break
@unknown default:
break
}
}
}
private class ColorPickerWheelInnerView: UIView {
private var brightnessView: UIView!
var brightness: CGFloat {
get { 1 - brightnessView.alpha }
set { brightnessView.alpha = 1 - newValue }
}
var handleLayout: (() -> Void)!
private var saturationMask: GradientView!
override init(frame: CGRect) {
super.init(frame: frame)
clipsToBounds = true
let hueView = GradientView()
hueView.translatesAutoresizingMaskIntoConstraints = false
hueView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
hueView.gradientLayer.type = .conic
hueView.gradientLayer.colors = Color.Component.hue.sliderTintColor(for: Color(red: 1, green: 0, blue: 0, alpha: 1)).map(\.uiColor.cgColor)
hueView.gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
hueView.gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)
hueView.gradientLayer.transform = CATransform3DMakeRotation(0.5 * .pi, 0, 0, 1)
addSubview(hueView)
let saturationView = UIView()
saturationView.translatesAutoresizingMaskIntoConstraints = false
saturationView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
saturationView.backgroundColor = .white
addSubview(saturationView)
saturationMask = GradientView()
saturationMask.gradientLayer.type = .radial
saturationMask.gradientLayer.colors = [UIColor.white.cgColor, UIColor.clear.cgColor]
saturationMask.gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
saturationMask.gradientLayer.endPoint = CGPoint(x: 1, y: 1)
saturationView.mask = saturationMask
brightnessView = UIView()
brightnessView.translatesAutoresizingMaskIntoConstraints = false
brightnessView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
brightnessView.backgroundColor = .black
addSubview(brightnessView)
}
convenience init() {
self.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = frame.size.height / 2
saturationMask.frame = bounds
handleLayout()
}
}

View File

@@ -1,403 +0,0 @@
//
// ColorWell.swift
// Alderis
//
// Created by Adam Demasi on 15/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
import CoreServices
/// ColorWell can be used to present the users color selection in your user interface. It
/// optionally also supports drag-and-drop operations.
///
/// By default, drop interactions are supported, which causes a `UIControl.Event.valueChanged` event
/// to be emitted. Optionally, drag operations can be enabled, allowing the color to be dropped
/// elsewhere.
///
/// You can also use `UIControl.Event.touchUpInside` to perform an action, such as to initialise
/// and present an instance of `ColorPickerViewController`.
@objc(HBColorWell)
open class ColorWell: UIControl {
/// Set the color to be displayed by the view.
@objc open var color: UIColor? {
get { colorView.backgroundColor }
set { colorView.backgroundColor = newValue }
}
/// Override the default border color if desired.
@objc open var borderColor: UIColor? {
didSet { updateBorderColor() }
}
/// Whether the user can begin a drag interaction from this view, allowing them to drop the color
/// into a supporting app. The default is `false`.
@objc open var isDragInteractionEnabled = false {
didSet { updateDragDropInteraction() }
}
/// Whether the user can end a drag interaction by dropping on this view, allowing them to drag a
/// color from a supporting app onto this view. The default is true.
///
/// To handle a color being dropped on this view, add an action for the `.valueChanged` event. For
/// example:
///
/// ```swift
/// colorWell.addTarget(self, action: #selector(self.handleColorDidChange(_:)), for: .valueChanged)
/// ```
@objc open var isDropInteractionEnabled = true {
didSet { updateDragDropInteraction() }
}
#if swift(>=5.3)
/// Whether the user can long press (iPhone) or right-click (Mac/iPad) the view, allowing them to
/// copy the color in various formats, or paste a color from another source.
///
/// To handle a color being pasted via the context menu, add an action for the `.valueChanged`
/// event. For example:
///
/// ```swift
/// colorWell.addTarget(self, action: #selector(self.handleColorDidChange(_:)), for: .valueChanged)
/// ```
///
/// Requires iOS 14 or newer.
@available(iOS 14, *)
open override var isContextMenuInteractionEnabled: Bool {
didSet { updateDragDropInteraction() }
}
#endif
private var colorView: UIView!
private var dragInteraction: UIDragInteraction!
private var dropInteraction: UIDropInteraction!
private var tapGestureRecognizer: UITapGestureRecognizer!
private var contextMenuTitle: String {
if let color = color {
return "Color: \(Color(uiColor: color).hexString())"
}
return "No color"
}
/// :nodoc:
override init(frame: CGRect) {
super.init(frame: frame)
setUp()
}
/// :nodoc:
required public init?(coder: NSCoder) {
super.init(coder: coder)
setUp()
}
private func setUp() {
clipsToBounds = true
backgroundColor = Assets.checkerboardPatternColor
borderColor = .white
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = .zero
layer.shadowOpacity = 0.75
layer.shadowRadius = 1
colorView = UIView()
colorView.translatesAutoresizingMaskIntoConstraints = false
colorView.clipsToBounds = true
addSubview(colorView)
dragInteraction = UIDragInteraction(delegate: self)
dragInteraction.isEnabled = true
dropInteraction = UIDropInteraction(delegate: self)
updateDragDropInteraction()
tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTapGestureRecognizerFired(_:)))
tapGestureRecognizer.isEnabled = false
addGestureRecognizer(tapGestureRecognizer)
#if swift(>=5.3)
if #available(iOS 14, *) {
isContextMenuInteractionEnabled = true
}
#endif
#if swift(>=5.5)
if #available(iOS 15, *) {
toolTip = contextMenuTitle
toolTipInteraction?.delegate = self
}
#endif
NSLayoutConstraint.activate([
self.widthAnchor.constraint(greaterThanOrEqualToConstant: UIFloat(32)),
self.heightAnchor.constraint(equalTo: self.widthAnchor),
colorView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
colorView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
colorView.topAnchor.constraint(equalTo: self.topAnchor),
colorView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
])
}
private func updateTapGestureRecognizer() {
let hasTouchUpActions = allControlEvents.contains(.touchUpInside)
if hasTouchUpActions {
accessibilityTraits.insert(.button)
} else {
accessibilityTraits.remove(.button)
}
tapGestureRecognizer.isEnabled = hasTouchUpActions
}
private func updateBorderColor() {
layer.borderColor = borderColor?.cgColor
}
private func updateDragDropInteraction() {
isUserInteractionEnabled = isDragInteractionEnabled || isDropInteractionEnabled
#if swift(>=5.3)
if #available(iOS 14, *) {
isUserInteractionEnabled = isUserInteractionEnabled || isContextMenuInteractionEnabled
}
#endif
if isDragInteractionEnabled {
addInteraction(dragInteraction)
} else {
removeInteraction(dragInteraction)
}
if isDropInteractionEnabled {
addInteraction(dropInteraction)
} else {
removeInteraction(dropInteraction)
}
}
/// :nodoc:
override open func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = frame.size.width / 2
layer.shadowPath = CGPath(ellipseIn: bounds, transform: nil)
colorView.layer.cornerRadius = layer.cornerRadius
}
/// :nodoc:
override open func didMoveToWindow() {
super.didMoveToWindow()
let scale = window?.screen.scale ?? 1
layer.borderWidth = (scale > 2 ? 2 : 1) / scale
}
/// :nodoc:
override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateBorderColor()
}
/// :nodoc:
open override func addTarget(_ target: Any?, action: Selector, for controlEvents: UIControl.Event) {
super.addTarget(target, action: action, for: controlEvents)
updateTapGestureRecognizer()
}
/// :nodoc:
@available(iOS 14, macCatalyst 14, *)
open override func addAction(_ action: UIAction, for controlEvents: UIControl.Event) {
super.addAction(action, for: controlEvents)
updateTapGestureRecognizer()
}
/// :nodoc:
open override func removeTarget(_ target: Any?, action: Selector?, for controlEvents: UIControl.Event) {
super.removeTarget(target, action: action, for: controlEvents)
updateTapGestureRecognizer()
}
/// :nodoc:
@available(iOS 14, macCatalyst 14, *)
open override func removeAction(_ action: UIAction, for controlEvents: UIControl.Event) {
super.removeAction(action, for: controlEvents)
updateTapGestureRecognizer()
}
/// :nodoc:
@available(iOS 14, macCatalyst 14, *)
open override func removeAction(identifiedBy actionIdentifier: UIAction.Identifier, for controlEvents: UIControl.Event) {
super.removeAction(identifiedBy: actionIdentifier, for: controlEvents)
updateTapGestureRecognizer()
}
@objc private func handleTapGestureRecognizerFired(_ sender: UITapGestureRecognizer) {
if sender.state == .ended {
sendActions(for: .touchUpInside)
}
}
}
/// :nodoc:
extension ColorWell { // UIResponder
open override var canBecomeFirstResponder: Bool { true }
open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
switch action {
case #selector(copy(_:)), #selector(copyHex), #selector(copyRGB), #selector(copyHSL),
#selector(copyObjC), #selector(copySwift):
return color != nil
case #selector(paste(_:)):
return UIPasteboard.general.hasColors || UIPasteboard.general.hasStrings
default:
return super.canPerformAction(action, withSender: sender)
}
}
open override func copy(_ sender: Any?) {
UIPasteboard.general.color = color
}
open override func paste(_ sender: Any?) {
if let color = UIPasteboard.general.color ?? UIColor(propertyListValue: UIPasteboard.general.string ?? "") {
self.color = color
sendActions(for: .valueChanged)
}
}
@objc private func copyHex(_ sender: Any?) {
UIPasteboard.general.string = Color(uiColor: color!).hexString
}
@objc private func copyRGB(_ sender: Any?) {
UIPasteboard.general.string = Color(uiColor: color!).rgbString
}
@objc private func copyHSL(_ sender: Any?) {
UIPasteboard.general.string = Color(uiColor: color!).hslString
}
@objc private func copyObjC(_ sender: Any?) {
UIPasteboard.general.string = Color(uiColor: color!).objcString
}
@objc private func copySwift(_ sender: Any?) {
UIPasteboard.general.string = Color(uiColor: color!).swiftString
}
}
/// :nodoc:
extension ColorWell: UIDragInteractionDelegate {
/// :nodoc:
public func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
guard let color = color else {
return []
}
let provider = NSItemProvider(object: color)
let item = UIDragItem(itemProvider: provider)
item.localObject = color
return [item]
}
}
/// :nodoc:
extension ColorWell: UIDropInteractionDelegate {
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
return session.items.count == 1 && session.canLoadObjects(ofClass: UIColor.self)
}
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
return UIDropProposal(operation: .copy)
}
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
session.loadObjects(ofClass: UIColor.self) { items in
if let color = items.first as? UIColor {
self.color = color
self.sendActions(for: .valueChanged)
}
}
}
}
#if swift(>=5.5)
/// :nodoc:
@available(iOS 15, *)
extension ColorWell: UIToolTipInteractionDelegate {
/// :nodoc:
public func toolTipInteraction(_ interaction: UIToolTipInteraction, configurationAt point: CGPoint) -> UIToolTipConfiguration? {
UIToolTipConfiguration(toolTip: contextMenuTitle)
}
}
#endif
#if swift(>=5.3)
/// :nodoc:
@available(iOS 13, *)
extension ColorWell { // UIContextMenuInteractionDelegate
/// :nodoc:
open override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: color, previewProvider: nil) { items in
var children = [UIMenuElement]()
if isCatalyst {
children += [
UIMenu(title: "", options: .displayInline, children: [
UICommand(title: self.contextMenuTitle,
action: #selector(self.doesNotRecognizeSelector(_:)),
attributes: .disabled)
])
]
}
children += items
var objcImageName = "chevron.left.slash.chevron.right"
var swiftImageName = "chevron.left.slash.chevron.right"
if #available(iOS 14, *) {
objcImageName = "curlybraces"
swiftImageName = "swift"
}
children += [
UIMenu(title: "", options: .displayInline, children: [
UICommand(title: "Copy as Hex",
image: UIImage(systemName: "number"),
action: #selector(self.copyHex(_:))),
UICommand(title: "Copy as RGB",
image: UIImage(systemName: "r.circle"),
action: #selector(self.copyRGB(_:))),
UICommand(title: "Copy as HSL",
image: UIImage(systemName: "h.circle"),
action: #selector(self.copyHSL(_:))),
UICommand(title: "Copy as Objective-C",
image: UIImage(systemName: objcImageName),
action: #selector(self.copyObjC(_:))),
UICommand(title: "Copy as Swift",
image: UIImage(systemName: swiftImageName),
action: #selector(self.copySwift(_:))),
])
]
return UIMenu(title: self.contextMenuTitle, children: children)
}
}
}
#endif
/// Deprecated. Use `ColorWell` instead.
@available(*, deprecated, renamed: "ColorWell")
@objc(HBColorPickerCircleView)
open class ColorPickerCircleView: ColorWell {}

View File

@@ -1,34 +0,0 @@
//
// DialogButton.swift
// Alderis
//
// Created by Adam Demasi on 28/9/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class DialogButton: UIButton {
var highlightBackgroundColor: UIColor?
init() {
super.init(frame: .zero)
addTarget(self, action: #selector(self.handleTouchDown), for: [.touchDown, .touchDragEnter])
addTarget(self, action: #selector(self.handleTouchUp), for: [.touchUpInside, .touchUpOutside, .touchDragExit, .touchCancel])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc private func handleTouchDown() {
backgroundColor = highlightBackgroundColor
}
@objc private func handleTouchUp() {
backgroundColor = nil
}
}

View File

@@ -1,18 +0,0 @@
//
// GradientView.swift
// Alderis
//
// Created by Adam Demasi on 11/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class GradientView: UIView {
override class var layerClass: AnyClass { CAGradientLayer.self }
// swiftlint:disable:next force_cast
var gradientLayer: CAGradientLayer { layer as! CAGradientLayer }
}

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>

View File

@@ -1,29 +0,0 @@
//
// NSBeep.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal typealias NSBeepType = @convention(c) () -> Void
internal let NSBeep: NSBeepType? = {
if isCatalyst,
let appkit = dlopen("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", RTLD_LAZY),
let beep = dlsym(appkit, "NSBeep") {
return unsafeBitCast(beep, to: NSBeepType.self)
}
return nil
}()
internal func beep() {
if isCatalyst {
NSBeep?()
} else {
let feedbackGenerator = UINotificationFeedbackGenerator()
feedbackGenerator.notificationOccurred(.error)
}
}

View File

@@ -1,60 +0,0 @@
//
// SeparatorView.swift
// Alderis
//
// Created by Adam Demasi on 12/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class SeparatorView: UIView {
enum Direction {
case horizontal, vertical
}
var direction: Direction {
didSet { updateConstraints() }
}
private var widthConstraint: NSLayoutConstraint!
private var heightConstraint: NSLayoutConstraint!
init(direction: Direction) {
self.direction = direction
super.init(frame: .zero)
backgroundColor = Assets.separatorColor
widthConstraint = widthAnchor.constraint(equalToConstant: 1)
heightConstraint = heightAnchor.constraint(equalToConstant: 1)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func updateConstraints() {
super.updateConstraints()
let constant = 1 / (window?.screen.scale ?? 1)
switch direction {
case .horizontal:
widthConstraint.isActive = false
heightConstraint.isActive = true
heightConstraint.constant = constant
case .vertical:
widthConstraint.isActive = true
heightConstraint.isActive = false
widthConstraint.constant = constant
}
}
override func didMoveToWindow() {
super.didMoveToWindow()
updateConstraints()
}
}

View File

@@ -1,86 +0,0 @@
//
// TextViewLabel.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
import SafariServices
internal class TextViewLabel: UITextView {
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
delegate = self
backgroundColor = nil
textContainerInset = .zero
self.textContainer.lineFragmentPadding = 0
isEditable = false
isScrollEnabled = false
adjustsFontForContentSizeCategory = true
}
convenience init() {
self.init(frame: .zero, textContainer: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
// 🧡 to https://stackoverflow.com/a/44878203/709376 for this
guard super.point(inside: point, with: event),
let position = closestPosition(to: point),
let range = tokenizer.rangeEnclosingPosition(position,
with: .character,
inDirection: .layout(.left)) else {
return false
}
let index = offset(from: beginningOfDocument, to: range.start)
return attributedText.attribute(.link, at: index, effectiveRange: nil) != nil
}
override var selectedRange: NSRange {
get { NSRange() }
set {}
}
private var viewController: UIViewController? {
var responder: UIResponder? = self
while responder != nil {
if let viewController = responder as? UIViewController {
return viewController
}
responder = responder?.next
}
return nil
}
}
extension TextViewLabel: UITextViewDelegate {
func textView(_ textView: UITextView, shouldInteractWith url: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
#if targetEnvironment(macCatalyst)
// No need to do anything custom.
return true
#else
switch interaction {
case .invokeDefaultAction:
let safariViewController = SFSafariViewController(url: url)
safariViewController.modalPresentationStyle = .formSheet
viewController?.present(safariViewController, animated: true)
return false
case .presentActions, .preview:
return true
@unknown default:
return true
}
#endif
}
}

View File

@@ -1,199 +0,0 @@
//
// UIColorAdditions.swift
// Alderis
//
// Created by Ryan Nair on 10/5/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
/// ColorPropertyListValue is a protocol representing types that can be passed to the\
/// `UIColor.init(propertyListValue:)` initialiser. `String` and `Array` both conform to this type.
///
/// - see: `UIColor.init(propertyListValue:)`
public protocol ColorPropertyListValue {}
/// A string can represent a `ColorPropertyListValue`.
///
/// - see: `UIColor.init(propertyListValue:)`
extension String: ColorPropertyListValue {}
/// An array of integers can represent a `ColorPropertyListValue`.
///
/// - see: `UIColor.init(propertyListValue:)`
extension Array: ColorPropertyListValue where Element: FixedWidthInteger {}
/// Alderis provides extensions to `UIColor` for the purpose of serializing and deserializing colors
/// into representations that can be stored in property lists, JSON, and similar formats.
public extension UIColor {
/// Initializes and returns a color object using data from the specified object.
///
/// The value is expected to be one of:
///
/// * An array of 3 or 4 integer RGB or RGBA color components, with values between 0 and 255 (e.g.
/// `[218, 192, 222]`)
/// * A CSS-style hex string, with an optional alpha component (e.g. `#DAC0DE` or `#DACODE55`)
/// * A short CSS-style hex string, with an optional alpha component (e.g. `#DC0` or `#DC05`)
///
/// Use `-[UIColor initWithHbcp_propertyListValue:]` to access this method from Objective-C.
///
/// - parameter value: The object to retrieve data from. See the discussion for the supported object
/// types.
/// - returns: An initialized color object, or nil if the value does not conform to the expected
/// type. The color information represented by this object is in the device RGB colorspace.
/// - see: `propertyListValue`
@nonobjc convenience init?(propertyListValue: ColorPropertyListValue?) {
if let array = propertyListValue as? [Int], array.count == 3 || array.count == 4 {
let floats = array.map(CGFloat.init(_:))
self.init(red: floats[0] / 255,
green: floats[1] / 255,
blue: floats[2] / 255,
alpha: array.count == 4 ? floats[3] : 1)
return
} else if var string = propertyListValue as? String {
if string.count == 4 || string.count == 5 {
let r = String(repeating: string[string.index(string.startIndex, offsetBy: 1)], count: 2)
let g = String(repeating: string[string.index(string.startIndex, offsetBy: 2)], count: 2)
let b = String(repeating: string[string.index(string.startIndex, offsetBy: 3)], count: 2)
let a = string.count == 5 ? String(repeating: string[string.index(string.startIndex, offsetBy: 4)], count: 2) : "FF"
string = r + g + b + a
}
var hex: UInt64 = 0
let scanner = Scanner(string: string)
guard scanner.scanString("#", into: nil),
scanner.scanHexInt64(&hex) else {
return nil
}
if string.count == 9 {
self.init(red: CGFloat((hex & 0xFF000000) >> 24) / 255,
green: CGFloat((hex & 0x00FF0000) >> 16) / 255,
blue: CGFloat((hex & 0x0000FF00) >> 8) / 255,
alpha: CGFloat((hex & 0x000000FF) >> 0) / 255)
return
} else {
var alpha: Float = 1
if scanner.scanString(":", into: nil) {
// Continue scanning to get the alpha component.
scanner.scanFloat(&alpha)
}
self.init(red: CGFloat((hex & 0xFF0000) >> 16) / 255,
green: CGFloat((hex & 0x00FF00) >> 8) / 255,
blue: CGFloat((hex & 0x0000FF) >> 0) / 255,
alpha: CGFloat(alpha))
return
}
}
return nil
}
/// Maps `init(propertyListValue:)` to Objective-C due to Swift limitations. This is an
/// implementation detail. Ignore this and use `UIColor(propertyListValue:)` or
/// `-[UIColor initWithHbcp_propertyListValue:]` as per usual.
///
/// - parameter value: The object to retrieve data from. See the discussion for the supported
/// object types.
/// - returns: An initialized color object, or nil if the value does not conform to the expected
/// type. The color information represented by this object is in the device RGB colorspace.
/// device RGB colorspace.
/// - see: `init(propertyListValue:)`
@objc(initWithHbcp_propertyListValue:)
convenience init?(_propertyListValueObjC propertyListValue: Any?) {
if let value = propertyListValue as? String {
self.init(propertyListValue: value)
} else if let value = propertyListValue as? [Int] {
self.init(propertyListValue: value)
} else {
return nil
}
}
/// Returns a string that represents the color.
///
/// The output is a string in the format `#AABBCC:0.5`, where the initial `#AABBCC` portion is a
/// 6-character CSS-style hex string, and the final `:0.5` portion represents the alpha value. If
/// the colors alpha value is `1`, the alpha portion is excluded.
///
/// If the color is dynamic, for instance if it is a UIKit system color, or initialised via
/// `UIColor(dynamicProvider:)`, the color that matches the current trait collection is used.
///
/// - returns: A string representing the color, in the format discussed above.
/// - see: `init(propertyListValue:)`
@objc(hbcp_propertyListValue)
var propertyListValue: String {
var alpha: CGFloat = 0
getRed(nil, green: nil, blue: nil, alpha: &alpha)
let color = Color(uiColor: self.withAlphaComponent(1))
let hexString = color.hexString()
let alphaString = alpha == 1 ? "" : String(format: ":%.5G", alpha)
return "\(hexString)\(alphaString)"
}
/// Returns a hexadecimal string that represents the color.
///
/// The output is a string in the format `#AABBCCDD`, where the initial `#AABBCC` portion is a
/// 6-character CSS-style hex string, and the final `DD` portion is the hexadecimal representation
/// of the alpha value, supported by [recent web browsers](https://caniuse.com/css-rrggbbaa).
///
/// If the color is dynamic, for instance if it is a UIKit system color, or initialised via
/// `UIColor(dynamicProvider:)`, the color that matches the current trait collection is used.
///
/// - returns: A string representing the color, in the format discussed above.
@objc(hbcp_hexString)
var hexString: String { Color(uiColor: self).hexString }
/// Returns an RGB string that represents the color.
///
/// The output is a string in the format of `rgba(170, 187, 204, 0.5)`, or `rgb(170, 187, 204)` if
/// the colors alpha value is `1`.
///
/// If the color is dynamic, for instance if it is a UIKit system color, or initialised via
/// `UIColor(dynamicProvider:)`, the color that matches the current trait collection is used.
///
/// - returns: A string representing the color, in the format discussed above.
@objc(hbcp_rgbString)
var rgbString: String { Color(uiColor: self).rgbString }
/// Returns an HSL string that represents the color.
///
/// The output is a string in the format of `hsla(170, 187, 204, 0.5)`, or `hsl(170, 187, 204)` if
/// the colors alpha value is `1`.
///
/// If the color is dynamic, for instance if it is a UIKit system color, or initialised via
/// `UIColor(dynamicProvider:)`, the color that matches the current trait collection is used.
///
/// - returns: A string representing the color, in the format discussed above.
@objc(hbcp_hslString)
var hslString: String { Color(uiColor: self).hslString }
/// Returns an Objective-C UIColor string that represents the color.
///
/// The output is a string in the format of
/// `[UIColor colorWithRed:0.667 green:0.733 blue:0.800 alpha:1.00]`.
///
/// If the color is dynamic, for instance if it is a UIKit system color, or initialised via
/// `UIColor(dynamicProvider:)`, the color that matches the current trait collection is used.
///
/// - returns: A string representing the color, in the format discussed above.
@objc(hbcp_objcString)
var objcString: String { Color(uiColor: self).objcString }
/// Returns a Swift UIColor string that represents the color.
///
/// The output is a string in the format of
/// `UIColor(red: 0.667, green: 0.733, blue: 0.800, alpha: 1.00)`.
///
/// If the color is dynamic, for instance if it is a UIKit system color, or initialised via
/// `UIColor(dynamicProvider:)`, the color that matches the current trait collection is used.
///
/// - returns: A string representing the color, in the format discussed above.
@objc(hbcp_swiftString)
var swiftString: String { Color(uiColor: self).swiftString }
}

View File

@@ -1,34 +0,0 @@
//
// UIFloat.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal let isCatalyst: Bool = {
if #available(iOS 13, *) {
return ProcessInfo.processInfo.isMacCatalystApp
}
return false
}()
// Catalyst iPad mode, with iOS UI at 0.77 scale
internal let isCatalystPad = isCatalyst && UIDevice.current.userInterfaceIdiom == .pad
// Catalyst Mac mode, with Mac UI at 1.00 scale
internal let isCatalystMac: Bool = {
#if swift(>=5.3)
if #available(iOS 14, *) {
return UIDevice.current.userInterfaceIdiom == .mac
}
#endif
return false
}()
// Inspired by https://www.highcaffeinecontent.com/blog/20220216-Where-Mac-Catalyst-Falls-Short
internal func UIFloat(_ value: CGFloat) -> CGFloat {
return floor(value * (isCatalystMac ? 0.77 : 1))
}

View File

@@ -1,32 +0,0 @@
//
// UIFontDescriptorAdditions.swift
// Alderis
//
// Created by Adam Demasi on 7/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal extension UIFontDescriptor.FeatureKey {
// Abstracts a messy API change made in iOS 15.
static var alderisFeature: Self {
#if swift(>=5.5)
if #available(iOS 15, *) {
return .type
}
#endif
return .featureIdentifier
}
static var alderisSelector: Self {
#if swift(>=5.5)
if #available(iOS 15, *) {
return .selector
}
#endif
return .typeIdentifier
}
}

View File

@@ -1,444 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
129B4F59BA5C9D60F07CE7E0 /* libPods-Alderis Demo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABFF0FA1430DE1F1C311810B /* libPods-Alderis Demo.a */; };
CF39D44B222BC07E001EF57F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CF39D44A222BC07E001EF57F /* Assets.xcassets */; };
CF6B3B9E2446A13C000A608B /* FirstViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF6B3B9D2446A13C000A608B /* FirstViewController.swift */; };
CF83082423F7819A00157D3F /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CF83082323F7819A00157D3F /* Launch Screen.storyboard */; };
CFE70278241A593200083903 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70277241A593200083903 /* AppDelegate.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
CF73D33E241F9C23000B1B10 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2B5DB4BF0F331C22D5DFB481 /* Pods-Alderis Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Alderis Demo.release.xcconfig"; path = "Target Support Files/Pods-Alderis Demo/Pods-Alderis Demo.release.xcconfig"; sourceTree = "<group>"; };
9FD89BFF752E9D684C11E887 /* Pods-Alderis Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Alderis Demo.debug.xcconfig"; path = "Target Support Files/Pods-Alderis Demo/Pods-Alderis Demo.debug.xcconfig"; sourceTree = "<group>"; };
ABFF0FA1430DE1F1C311810B /* libPods-Alderis Demo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Alderis Demo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
CF39D43E222BC07C001EF57F /* Alderis Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Alderis Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
CF39D44A222BC07E001EF57F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
CF39D44F222BC07E001EF57F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CF6B3B9D2446A13C000A608B /* FirstViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = "<group>"; };
CF83082323F7819A00157D3F /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
CFCF774D242113EE00379864 /* AlderisDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AlderisDemo.entitlements; sourceTree = "<group>"; };
CFE70277241A593200083903 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CF39D43B222BC07C001EF57F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
129B4F59BA5C9D60F07CE7E0 /* libPods-Alderis Demo.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
13755DEE92D2481708433C7E /* Frameworks */ = {
isa = PBXGroup;
children = (
ABFF0FA1430DE1F1C311810B /* libPods-Alderis Demo.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
AB49FDA0EE3B301C0383D6FF /* Pods */ = {
isa = PBXGroup;
children = (
9FD89BFF752E9D684C11E887 /* Pods-Alderis Demo.debug.xcconfig */,
2B5DB4BF0F331C22D5DFB481 /* Pods-Alderis Demo.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
CF39D435222BC07C001EF57F = {
isa = PBXGroup;
children = (
CF39D440222BC07C001EF57F /* Alderis Demo */,
CF39D43F222BC07C001EF57F /* Products */,
AB49FDA0EE3B301C0383D6FF /* Pods */,
13755DEE92D2481708433C7E /* Frameworks */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 1;
};
CF39D43F222BC07C001EF57F /* Products */ = {
isa = PBXGroup;
children = (
CF39D43E222BC07C001EF57F /* Alderis Demo.app */,
);
name = Products;
sourceTree = "<group>";
};
CF39D440222BC07C001EF57F /* Alderis Demo */ = {
isa = PBXGroup;
children = (
CFCF774D242113EE00379864 /* AlderisDemo.entitlements */,
CF83082323F7819A00157D3F /* Launch Screen.storyboard */,
CFE70277241A593200083903 /* AppDelegate.swift */,
CF6B3B9D2446A13C000A608B /* FirstViewController.swift */,
CF39D44A222BC07E001EF57F /* Assets.xcassets */,
CF39D44F222BC07E001EF57F /* Info.plist */,
);
path = "Alderis Demo";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
CF39D43D222BC07C001EF57F /* Alderis Demo */ = {
isa = PBXNativeTarget;
buildConfigurationList = CF39D454222BC07E001EF57F /* Build configuration list for PBXNativeTarget "Alderis Demo" */;
buildPhases = (
B02FB21B4CF370106F8C5ADD /* [CP] Check Pods Manifest.lock */,
CF39D43A222BC07C001EF57F /* Sources */,
CF39D43B222BC07C001EF57F /* Frameworks */,
CF39D43C222BC07C001EF57F /* Resources */,
CF73D33E241F9C23000B1B10 /* Embed Frameworks */,
CF79DA2F25171E2D00F17BCB /* SwiftLint */,
638C9DB382A92024C20F1301 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Alderis Demo";
productName = "Alderis Demo";
productReference = CF39D43E222BC07C001EF57F /* Alderis Demo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CF39D436222BC07C001EF57F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1330;
ORGANIZATIONNAME = "HASHBANG Productions";
TargetAttributes = {
CF39D43D222BC07C001EF57F = {
CreatedOnToolsVersion = 10.0;
LastSwiftMigration = 1130;
};
};
};
buildConfigurationList = CF39D439222BC07C001EF57F /* Build configuration list for PBXProject "Alderis Demo" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CF39D435222BC07C001EF57F;
productRefGroup = CF39D43F222BC07C001EF57F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CF39D43D222BC07C001EF57F /* Alderis Demo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CF39D43C222BC07C001EF57F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CF83082423F7819A00157D3F /* Launch Screen.storyboard in Resources */,
CF39D44B222BC07E001EF57F /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
638C9DB382A92024C20F1301 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Alderis Demo/Pods-Alderis Demo-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Alderis Demo/Pods-Alderis Demo-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Alderis Demo/Pods-Alderis Demo-resources.sh\"\n";
showEnvVarsInLog = 0;
};
B02FB21B4CF370106F8C5ADD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Alderis Demo-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
CF79DA2F25171E2D00F17BCB /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = SwiftLint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\n\tswiftlint\nelse\n\techo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CF39D43A222BC07C001EF57F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CFE70278241A593200083903 /* AppDelegate.swift in Sources */,
CF6B3B9E2446A13C000A608B /* FirstViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
CF39D452222BC07E001EF57F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
CF39D453222BC07E001EF57F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
CF39D455222BC07E001EF57F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9FD89BFF752E9D684C11E887 /* Pods-Alderis Demo.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
ASSETCATALOG_COMPILER_SKIP_APP_STORE_DEPLOYMENT = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Alderis Demo/AlderisDemo.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
DEVELOPMENT_TEAM = N2LN9ZT493;
INFOPLIST_FILE = "Alderis Demo/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = ws.hbang.AlderisDemo;
PRODUCT_NAME = "Alderis Demo";
SUPPORTS_MACCATALYST = YES;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
};
name = Debug;
};
CF39D456222BC07E001EF57F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2B5DB4BF0F331C22D5DFB481 /* Pods-Alderis Demo.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
ASSETCATALOG_COMPILER_SKIP_APP_STORE_DEPLOYMENT = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Alderis Demo/AlderisDemo.entitlements";
CODE_SIGN_STYLE = Automatic;
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
INFOPLIST_FILE = "Alderis Demo/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = ws.hbang.AlderisDemo;
PRODUCT_NAME = "Alderis Demo";
SUPPORTS_MACCATALYST = YES;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CF39D439222BC07C001EF57F /* Build configuration list for PBXProject "Alderis Demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF39D452222BC07E001EF57F /* Debug */,
CF39D453222BC07E001EF57F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CF39D454222BC07E001EF57F /* Build configuration list for PBXNativeTarget "Alderis Demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF39D455222BC07E001EF57F /* Debug */,
CF39D456222BC07E001EF57F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CF39D436222BC07C001EF57F /* Project object */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Alderis Demo.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1330"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF39D43D222BC07C001EF57F"
BuildableName = "Alderis Demo.app"
BlueprintName = "Alderis Demo"
ReferencedContainer = "container:Alderis Demo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF39D43D222BC07C001EF57F"
BuildableName = "Alderis Demo.app"
BlueprintName = "Alderis Demo"
ReferencedContainer = "container:Alderis Demo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF39D43D222BC07C001EF57F"
BuildableName = "Alderis Demo.app"
BlueprintName = "Alderis Demo"
ReferencedContainer = "container:Alderis Demo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:../Alderis.xcodeproj">
</FileRef>
<FileRef
location = "group:Alderis Demo.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

View File

@@ -1,35 +0,0 @@
//
// AppDelegate.swift
// Alderis Demo
//
// Created by Adam Demasi on 12/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
// swiftlint:disable:next line_length
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window!.tintColor = UIColor(hue: 0.939614, saturation: 0.811765, brightness: 0.333333, alpha: 1)
let tabBarController = UITabBarController()
let viewController = UINavigationController(rootViewController: FirstViewController())
if #available(iOS 13, *) {
let tabIcon = UIImage(systemName: "paintbrush.fill")?.withBaselineOffset(fromBottom: 2)
viewController.tabBarItem = UITabBarItem(title: "Alderis Demo", image: tabIcon, tag: 0)
}
tabBarController.viewControllers = [viewController]
window!.rootViewController = tabBarController
window!.makeKeyAndVisible()
return true
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,102 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "AppIcon120x120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "AppIcon180x180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "AppIcon152x152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "AppIcon167x167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@@ -1,321 +0,0 @@
//
// FirstViewController.swift
// Alderis Demo
//
// Created by Adam Demasi on 15/4/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
import Alderis
class FirstViewController: UIViewController {
private var color = UIColor(hue: 0.939614, saturation: 0.811765, brightness: 0.333333, alpha: 1)
private var colorWell: ColorWell!
private var uikitWell: UIView?
// swiftlint:disable:next function_body_length
override func viewDidLoad() {
super.viewDidLoad()
title = "Alderis Demo"
if #available(iOS 13, *) {
view.backgroundColor = .systemBackground
} else {
view.backgroundColor = .white
}
#if targetEnvironment(macCatalyst)
navigationController?.isNavigationBarHidden = true
#endif
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = 10
view.addSubview(stackView)
let mainButton = UIButton(type: .system)
if #available(iOS 15, *) {
var config = UIButton.Configuration.filled()
config.buttonSize = .large
mainButton.configuration = config
} else {
mainButton.titleLabel!.font = UIFont.systemFont(ofSize: 34, weight: .semibold)
}
mainButton.setTitle("Present", for: .normal)
mainButton.addTarget(self, action: #selector(self.presentColorPicker), for: .touchUpInside)
stackView.addArrangedSubview(mainButton)
// swiftlint:disable comma
let buttons: [(title: String, action: Selector)] = [
("Present with customised title", #selector(presentColorPickerCustomisedTitle)),
("Present with customised initial tab", #selector(presentColorPickerCustomisedInitialTab)),
("Present with customised tabs", #selector(presentColorPickerCustomisedTabs)),
("Present with tabs hidden", #selector(presentColorPickerNoTabs)),
("Present with customised title, tabs hidden", #selector(presentColorPickerCustomisedTitleNoTabs)),
("Present without alpha", #selector(presentColorPickerNoAlpha)),
("Present without overriding Smart Invert", #selector(presentColorPickerNoOverrideSmartInvert)),
("Present using deprecated API", #selector(presentColorPickerDeprecatedAPI)),
("Present UIKit Color Picker", #selector(presentUIKitColorPicker))
]
// swiftlint:enable comma
for item in buttons {
let button = UIButton(type: .system)
if #available(iOS 15, *) {
var config = UIButton.Configuration.plain()
config.buttonSize = .mini
config.macIdiomStyle = .borderlessTinted
button.configuration = config
}
button.setTitle(item.title, for: .normal)
button.addTarget(self, action: item.action, for: .touchUpInside)
stackView.addArrangedSubview(button)
}
let spacerView = UIView()
stackView.addArrangedSubview(spacerView)
let wellsLabel = UILabel()
wellsLabel.font = UIFont.preferredFont(forTextStyle: .headline)
wellsLabel.textAlignment = .center
wellsLabel.text = "Color wells (try out drag and drop!)"
stackView.addArrangedSubview(wellsLabel)
colorWell = ColorWell()
colorWell.isDragInteractionEnabled = true
colorWell.isDropInteractionEnabled = true
colorWell.addTarget(self, action: #selector(self.colorWellValueChanged(_:)), for: .valueChanged)
colorWell.addTarget(self, action: #selector(self.presentColorPicker), for: .touchUpInside)
let dragOrDropColorWell = ColorWell()
dragOrDropColorWell.isDragInteractionEnabled = true
dragOrDropColorWell.isDropInteractionEnabled = true
dragOrDropColorWell.color = .systemPurple
let nonDraggableWell = ColorWell()
nonDraggableWell.isDragInteractionEnabled = false
nonDraggableWell.isDropInteractionEnabled = true
nonDraggableWell.color = .systemOrange
let nonDroppableWell = ColorWell()
nonDroppableWell.isDragInteractionEnabled = true
nonDroppableWell.isDropInteractionEnabled = false
nonDroppableWell.color = .systemTeal
let nonDragOrDropWell = ColorWell()
nonDragOrDropWell.isDragInteractionEnabled = false
nonDragOrDropWell.isDropInteractionEnabled = false
nonDragOrDropWell.color = .systemGreen
let wellsStackView = UIStackView(arrangedSubviews: [colorWell,
dragOrDropColorWell,
nonDraggableWell,
nonDroppableWell,
nonDragOrDropWell])
wellsStackView.translatesAutoresizingMaskIntoConstraints = false
wellsStackView.axis = .horizontal
wellsStackView.alignment = .center
wellsStackView.spacing = 10
if #available(iOS 14, *) {
let uikitWell = UIColorWell()
uikitWell.addTarget(self, action: #selector(self.uikitColorWellValueChanged(_:)), for: .valueChanged)
wellsStackView.addArrangedSubview(uikitWell)
self.uikitWell = uikitWell
}
stackView.addArrangedSubview(wellsStackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15),
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
spacerView.heightAnchor.constraint(equalToConstant: 0)
])
var isMac = false
if #available(iOS 14, *) {
isMac = UIDevice.current.userInterfaceIdiom == .mac
}
NSLayoutConstraint.activate(wellsStackView.arrangedSubviews.flatMap { view in
[
view.widthAnchor.constraint(equalToConstant: isMac ? 24 : 32),
view.heightAnchor.constraint(equalTo: view.widthAnchor)
]
})
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.window!.tintColor = color
colorWell.color = color
if #available(iOS 14, *),
let uikitWell = uikitWell as? UIColorWell {
uikitWell.selectedColor = color
}
}
@objc func colorWellValueChanged(_ sender: ColorWell) {
NSLog("Color well value changed with value %@", String(describing: sender.color))
view.window!.tintColor = sender.color
if #available(iOS 14, *),
let uikitWell = uikitWell as? UIColorWell {
uikitWell.selectedColor = sender.color
}
}
@available(iOS 14, *)
@objc func uikitColorWellValueChanged(_ sender: UIColorWell) {
NSLog("UIKit color well value changed with value %@", String(describing: sender.selectedColor))
view.window!.tintColor = sender.selectedColor
colorWell.color = sender.selectedColor
}
@objc func presentColorPicker(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerCustomisedTitle(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
configuration.title = "Select an Awesome Color"
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerCustomisedInitialTab(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
configuration.initialTab = .map
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerCustomisedTabs(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
configuration.visibleTabs = [.map, .sliders]
configuration.initialTab = .sliders
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerNoAlpha(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color.withAlphaComponent(0.5))
configuration.supportsAlpha = false
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerNoTabs(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
configuration.showTabs = false
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerCustomisedTitleNoTabs(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
configuration.title = "Select an Awesome Color"
configuration.showTabs = false
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerNoOverrideSmartInvert(_ sender: UIView) {
let configuration = ColorPickerConfiguration(color: color)
configuration.overrideSmartInvert = false
let colorPickerViewController = ColorPickerViewController(configuration: configuration)
colorPickerViewController.delegate = self
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentColorPickerDeprecatedAPI(_ sender: UIView) {
let colorPickerViewController = ColorPickerViewController()
colorPickerViewController.delegate = self
colorPickerViewController.color = color
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
}
@objc func presentUIKitColorPicker(_ sender: UIView) {
if #available(iOS 14, *) {
let colorPickerViewController = UIColorPickerViewController()
colorPickerViewController.delegate = self
colorPickerViewController.selectedColor = color
colorPickerViewController.popoverPresentationController?.sourceView = sender
tabBarController!.present(colorPickerViewController, animated: true)
} else {
fatalError("UIColorPickerViewController is only available as of iOS 14")
}
}
}
extension FirstViewController: ColorPickerDelegate {
func colorPicker(_ colorPicker: ColorPickerViewController, didSelect color: UIColor) {
NSLog("User selected color %@ (%@)", color.propertyListValue, String(describing: color))
self.color = color
view.window!.tintColor = color
colorWell.color = color
}
func colorPicker(_ colorPicker: ColorPickerViewController, didAccept color: UIColor) {
NSLog("User accepted color %@ (%@)", color.propertyListValue, String(describing: color))
}
func colorPickerDidCancel(_ colorPicker: ColorPickerViewController) {
NSLog("Color picker cancelled")
}
}
@available(iOS 14, *)
extension FirstViewController: UIColorPickerViewControllerDelegate {
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
NSLog("UIKit color picker value changed with color %@ (%@)",
viewController.selectedColor.propertyListValue,
String(describing: viewController.selectedColor))
color = viewController.selectedColor
view.window!.tintColor = viewController.selectedColor
if let uikitWell = uikitWell as? UIColorWell {
uikitWell.selectedColor = viewController.selectedColor
}
}
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
NSLog("UIKit color picker finished")
}
}

View File

@@ -1,19 +0,0 @@
//
// HBColorPickerSectionHeaderView.h
// Alderis Demo
//
// Created by Adam Demasi on 31/3/19.
// Copyright © 2019 HASHBANG Productions. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface HBColorPickerSectionHeaderView : UICollectionReusableView
@property (nonatomic, strong) UILabel *titleLabel;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,43 +0,0 @@
//
// HBColorPickerSectionHeaderView.m
// Alderis Demo
//
// Created by Adam Demasi on 31/3/19.
// Copyright © 2019 HASHBANG Productions. All rights reserved.
//
#import "HBColorPickerSectionHeaderView.h"
#import "CompactConstraint.h"
@implementation HBColorPickerSectionHeaderView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
_titleLabel.font = [UIFont boldSystemFontOfSize:18.f];
[self addSubview:_titleLabel];
[self hb_addCompactConstraints:@[
@"titleLabel.left = self.left + horizontalMargin",
@"titleLabel.right = self.right - horizontalMargin",
@"titleLabel.top = self.top + topMargin",
@"titleLabel.bottom = self.bottom - bottomMargin"
]
metrics:@{
@"horizontalMargin": @15.f,
@"topMargin": @10.f,
@"bottomMargin": @0.f
}
views:@{
@"self": self,
@"titleLabel": _titleLabel
}];
}
return self;
}
@end

View File

@@ -1,17 +0,0 @@
//
// HBColorPickerSwatchCell.h
// Alderis Demo
//
// Created by Adam Demasi on 4/3/19.
// Copyright © 2019 HASHBANG Productions. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface HBColorPickerSwatchCell : UICollectionViewCell
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,32 +0,0 @@
//
// HBColorPickerSwatchCell.m
// Alderis Demo
//
// Created by Adam Demasi on 4/3/19.
// Copyright © 2019 HASHBANG Productions. All rights reserved.
//
#import "HBColorPickerSwatchCell.h"
@implementation HBColorPickerSwatchCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.clipsToBounds = YES;
// self.layer.cornerRadius = 22.f;
// self.layer.borderColor = [UIColor grayColor].CGColor;
}
return self;
}
- (void)didMoveToWindow {
[super didMoveToWindow];
// CGFloat scale = self.window.screen.scale ?: 1.f;
// self.layer.borderWidth = scale > 2.f ? 2.f / scale : 1.f / scale;
}
@end

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Alderis Demo</string>
<key>CFBundleDisplayName</key>
<string>Alderis Demo</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>Launch Screen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More