Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
Material
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
Material
Commits
52972dae
Unverified
Commit
52972dae
authored
Sep 23, 2016
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
development: updated Card and ImageCard
parent
29eff722
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
751 additions
and
600 deletions
+751
-600
Examples/Material.xcworkspace/contents.xcworkspacedata
+3
-0
Examples/Programmatic/Card/Card/ViewController.swift
+8
-9
Examples/Programmatic/ImageCard/ImageCard.xcodeproj/project.pbxproj
+309
-0
Examples/Programmatic/ImageCard/ImageCard.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+7
-0
Examples/Programmatic/ImageCard/ImageCard/AppDelegate.swift
+45
-0
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/AppIcon.appiconset/Contents.json
+94
-0
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/Contents.json
+7
-0
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/CosmicMind.imageset/Contents.json
+22
-0
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/CosmicMind.imageset/CosmicMind.png
+0
-0
Examples/Programmatic/ImageCard/ImageCard/Base.lproj/LaunchScreen.storyboard
+27
-0
Examples/Programmatic/ImageCard/ImageCard/Info.plist
+44
-0
Examples/Programmatic/ImageCard/ImageCard/ViewController.swift
+100
-0
Sources/iOS/Card.swift
+22
-40
Sources/iOS/ImageCard.swift
+63
-551
No files found.
Examples/Material.xcworkspace/contents.xcworkspacedata
View file @
52972dae
...
@@ -23,6 +23,9 @@
...
@@ -23,6 +23,9 @@
location =
"group:Programmatic/Card/Card.xcodeproj"
>
location =
"group:Programmatic/Card/Card.xcodeproj"
>
</FileRef>
</FileRef>
<FileRef
<FileRef
location =
"group:Programmatic/ImageCard/ImageCard.xcodeproj"
>
</FileRef>
<FileRef
location =
"group:Programmatic/Layer/Layer.xcodeproj"
>
location =
"group:Programmatic/Layer/Layer.xcodeproj"
>
</FileRef>
</FileRef>
<FileRef
<FileRef
...
...
Examples/Programmatic/Card/Card/ViewController.swift
View file @
52972dae
...
@@ -32,7 +32,7 @@ import UIKit
...
@@ -32,7 +32,7 @@ import UIKit
import
Material
import
Material
class
ViewController
:
UIViewController
{
class
ViewController
:
UIViewController
{
private
var
t
itleB
ar
:
Toolbar
!
private
var
t
oolb
ar
:
Toolbar
!
private
var
contentView
:
UILabel
!
private
var
contentView
:
UILabel
!
private
var
bottomBar
:
Bar
!
private
var
bottomBar
:
Bar
!
private
var
favoriteButton
:
IconButton
!
private
var
favoriteButton
:
IconButton
!
...
@@ -41,18 +41,18 @@ class ViewController: UIViewController {
...
@@ -41,18 +41,18 @@ class ViewController: UIViewController {
super
.
viewDidLoad
()
super
.
viewDidLoad
()
view
.
backgroundColor
=
Color
.
grey
.
lighten5
view
.
backgroundColor
=
Color
.
grey
.
lighten5
prepareT
itleB
ar
()
prepareT
oolb
ar
()
prepareContentView
()
prepareContentView
()
prepareFavoriteButton
()
prepareFavoriteButton
()
prepareBottomBar
()
prepareBottomBar
()
prepareCard
()
prepareCard
()
}
}
private
func
prepareT
itleB
ar
()
{
private
func
prepareT
oolb
ar
()
{
t
itleB
ar
=
Toolbar
()
t
oolb
ar
=
Toolbar
()
t
itleB
ar
.
title
=
"Title"
t
oolb
ar
.
title
=
"Title"
t
itleB
ar
.
detail
=
"Detail Description"
t
oolb
ar
.
detail
=
"Detail Description"
t
itleB
ar
.
backgroundColor
=
nil
t
oolb
ar
.
backgroundColor
=
nil
}
}
private
func
prepareContentView
()
{
private
func
prepareContentView
()
{
...
@@ -75,8 +75,7 @@ class ViewController: UIViewController {
...
@@ -75,8 +75,7 @@ class ViewController: UIViewController {
private
func
prepareCard
()
{
private
func
prepareCard
()
{
let
card
=
Card
()
let
card
=
Card
()
card
.
pulseAnimation
=
.
pointWithBacking
card
.
toolbar
=
toolbar
card
.
titleBar
=
titleBar
card
.
contentView
=
contentView
card
.
contentView
=
contentView
card
.
bottomBar
=
bottomBar
card
.
bottomBar
=
bottomBar
...
...
Examples/Programmatic/ImageCard/ImageCard.xcodeproj/project.pbxproj
0 → 100644
View file @
52972dae
// !$*UTF8*$!
{
archiveVersion
=
1
;
classes
=
{
};
objectVersion
=
46
;
objects
=
{
/* Begin PBXBuildFile section */
9631A7A81D95ABB900CFB109
/* AppDelegate.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
9631A7A71D95ABB900CFB109
/* AppDelegate.swift */
;
};
9631A7AA1D95ABB900CFB109
/* ViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
9631A7A91D95ABB900CFB109
/* ViewController.swift */
;
};
9631A7AF1D95ABB900CFB109
/* Assets.xcassets in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
9631A7AE1D95ABB900CFB109
/* Assets.xcassets */
;
};
9631A7B21D95ABB900CFB109
/* LaunchScreen.storyboard in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
9631A7B01D95ABB900CFB109
/* LaunchScreen.storyboard */
;
};
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9631A7BC1D95ADAE00CFB109
/* Embed Frameworks */
=
{
isa
=
PBXCopyFilesBuildPhase
;
buildActionMask
=
2147483647
;
dstPath
=
""
;
dstSubfolderSpec
=
10
;
files
=
(
);
name
=
"Embed Frameworks"
;
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9631A7A41D95ABB900CFB109
/* ImageCard.app */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
wrapper.application
;
includeInIndex
=
0
;
path
=
ImageCard.app
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
9631A7A71D95ABB900CFB109
/* AppDelegate.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
AppDelegate.swift
;
sourceTree
=
"<group>"
;
};
9631A7A91D95ABB900CFB109
/* ViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ViewController.swift
;
sourceTree
=
"<group>"
;
};
9631A7AE1D95ABB900CFB109
/* Assets.xcassets */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
folder.assetcatalog
;
path
=
Assets.xcassets
;
sourceTree
=
"<group>"
;
};
9631A7B11D95ABB900CFB109
/* Base */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
file.storyboard
;
name
=
Base
;
path
=
Base.lproj/LaunchScreen.storyboard
;
sourceTree
=
"<group>"
;
};
9631A7B31D95ABB900CFB109
/* Info.plist */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
text.plist.xml
;
path
=
Info.plist
;
sourceTree
=
"<group>"
;
};
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
9631A7A11D95ABB900CFB109
/* Frameworks */
=
{
isa
=
PBXFrameworksBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9631A79B1D95ABB900CFB109
=
{
isa
=
PBXGroup
;
children
=
(
9631A7A61D95ABB900CFB109
/* ImageCard */
,
9631A7A51D95ABB900CFB109
/* Products */
,
);
sourceTree
=
"<group>"
;
};
9631A7A51D95ABB900CFB109
/* Products */
=
{
isa
=
PBXGroup
;
children
=
(
9631A7A41D95ABB900CFB109
/* ImageCard.app */
,
);
name
=
Products
;
sourceTree
=
"<group>"
;
};
9631A7A61D95ABB900CFB109
/* ImageCard */
=
{
isa
=
PBXGroup
;
children
=
(
9631A7A71D95ABB900CFB109
/* AppDelegate.swift */
,
9631A7A91D95ABB900CFB109
/* ViewController.swift */
,
9631A7AE1D95ABB900CFB109
/* Assets.xcassets */
,
9631A7B01D95ABB900CFB109
/* LaunchScreen.storyboard */
,
9631A7B31D95ABB900CFB109
/* Info.plist */
,
);
path
=
ImageCard
;
sourceTree
=
"<group>"
;
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
9631A7A31D95ABB900CFB109
/* ImageCard */
=
{
isa
=
PBXNativeTarget
;
buildConfigurationList
=
9631A7B61D95ABB900CFB109
/* Build configuration list for PBXNativeTarget "ImageCard" */
;
buildPhases
=
(
9631A7A01D95ABB900CFB109
/* Sources */
,
9631A7A11D95ABB900CFB109
/* Frameworks */
,
9631A7A21D95ABB900CFB109
/* Resources */
,
9631A7BC1D95ADAE00CFB109
/* Embed Frameworks */
,
);
buildRules
=
(
);
dependencies
=
(
);
name
=
ImageCard
;
productName
=
ImageCard
;
productReference
=
9631A7A41D95ABB900CFB109
/* ImageCard.app */
;
productType
=
"com.apple.product-type.application"
;
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
9631A79C1D95ABB900CFB109
/* Project object */
=
{
isa
=
PBXProject
;
attributes
=
{
LastSwiftUpdateCheck
=
0800
;
LastUpgradeCheck
=
0800
;
ORGANIZATIONNAME
=
CosmicMind
;
TargetAttributes
=
{
9631A7A31D95ABB900CFB109
=
{
CreatedOnToolsVersion
=
8.0
;
ProvisioningStyle
=
Automatic
;
};
};
};
buildConfigurationList
=
9631A79F1D95ABB900CFB109
/* Build configuration list for PBXProject "ImageCard" */
;
compatibilityVersion
=
"Xcode 3.2"
;
developmentRegion
=
English
;
hasScannedForEncodings
=
0
;
knownRegions
=
(
en
,
Base
,
);
mainGroup
=
9631A79B1D95ABB900CFB109
;
productRefGroup
=
9631A7A51D95ABB900CFB109
/* Products */
;
projectDirPath
=
""
;
projectRoot
=
""
;
targets
=
(
9631A7A31D95ABB900CFB109
/* ImageCard */
,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
9631A7A21D95ABB900CFB109
/* Resources */
=
{
isa
=
PBXResourcesBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
9631A7B21D95ABB900CFB109
/* LaunchScreen.storyboard in Resources */
,
9631A7AF1D95ABB900CFB109
/* Assets.xcassets in Resources */
,
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
9631A7A01D95ABB900CFB109
/* Sources */
=
{
isa
=
PBXSourcesBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
9631A7AA1D95ABB900CFB109
/* ViewController.swift in Sources */
,
9631A7A81D95ABB900CFB109
/* AppDelegate.swift in Sources */
,
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
9631A7B01D95ABB900CFB109
/* LaunchScreen.storyboard */
=
{
isa
=
PBXVariantGroup
;
children
=
(
9631A7B11D95ABB900CFB109
/* Base */
,
);
name
=
LaunchScreen.storyboard
;
sourceTree
=
"<group>"
;
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
9631A7B41D95ABB900CFB109
/* Debug */
=
{
isa
=
XCBuildConfiguration
;
buildSettings
=
{
ALWAYS_SEARCH_USER_PATHS
=
NO
;
CLANG_ANALYZER_NONNULL
=
YES
;
CLANG_CXX_LANGUAGE_STANDARD
=
"gnu++0x"
;
CLANG_CXX_LIBRARY
=
"libc++"
;
CLANG_ENABLE_MODULES
=
YES
;
CLANG_ENABLE_OBJC_ARC
=
YES
;
CLANG_WARN_BOOL_CONVERSION
=
YES
;
CLANG_WARN_CONSTANT_CONVERSION
=
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_OBJC_ROOT_CLASS
=
YES_ERROR
;
CLANG_WARN_SUSPICIOUS_MOVES
=
YES
;
CLANG_WARN_UNREACHABLE_CODE
=
YES
;
CLANG_WARN__DUPLICATE_METHOD_MATCH
=
YES
;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]"
=
"iPhone Developer"
;
COPY_PHASE_STRIP
=
NO
;
DEBUG_INFORMATION_FORMAT
=
dwarf
;
ENABLE_STRICT_OBJC_MSGSEND
=
YES
;
ENABLE_TESTABILITY
=
YES
;
GCC_C_LANGUAGE_STANDARD
=
gnu99
;
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
=
10.0
;
MTL_ENABLE_DEBUG_INFO
=
YES
;
ONLY_ACTIVE_ARCH
=
YES
;
SDKROOT
=
iphoneos
;
SWIFT_ACTIVE_COMPILATION_CONDITIONS
=
DEBUG
;
SWIFT_OPTIMIZATION_LEVEL
=
"-Onone"
;
TARGETED_DEVICE_FAMILY
=
"1,2"
;
};
name
=
Debug
;
};
9631A7B51D95ABB900CFB109
/* Release */
=
{
isa
=
XCBuildConfiguration
;
buildSettings
=
{
ALWAYS_SEARCH_USER_PATHS
=
NO
;
CLANG_ANALYZER_NONNULL
=
YES
;
CLANG_CXX_LANGUAGE_STANDARD
=
"gnu++0x"
;
CLANG_CXX_LIBRARY
=
"libc++"
;
CLANG_ENABLE_MODULES
=
YES
;
CLANG_ENABLE_OBJC_ARC
=
YES
;
CLANG_WARN_BOOL_CONVERSION
=
YES
;
CLANG_WARN_CONSTANT_CONVERSION
=
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_OBJC_ROOT_CLASS
=
YES_ERROR
;
CLANG_WARN_SUSPICIOUS_MOVES
=
YES
;
CLANG_WARN_UNREACHABLE_CODE
=
YES
;
CLANG_WARN__DUPLICATE_METHOD_MATCH
=
YES
;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]"
=
"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
=
gnu99
;
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
=
10.0
;
MTL_ENABLE_DEBUG_INFO
=
NO
;
SDKROOT
=
iphoneos
;
SWIFT_OPTIMIZATION_LEVEL
=
"-Owholemodule"
;
TARGETED_DEVICE_FAMILY
=
"1,2"
;
VALIDATE_PRODUCT
=
YES
;
};
name
=
Release
;
};
9631A7B71D95ABB900CFB109
/* Debug */
=
{
isa
=
XCBuildConfiguration
;
buildSettings
=
{
ASSETCATALOG_COMPILER_APPICON_NAME
=
AppIcon
;
INFOPLIST_FILE
=
ImageCard/Info.plist
;
LD_RUNPATH_SEARCH_PATHS
=
"$(inherited) @executable_path/Frameworks"
;
PRODUCT_BUNDLE_IDENTIFIER
=
io.cosmicmind.ImageCard
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
SWIFT_VERSION
=
3.0
;
};
name
=
Debug
;
};
9631A7B81D95ABB900CFB109
/* Release */
=
{
isa
=
XCBuildConfiguration
;
buildSettings
=
{
ASSETCATALOG_COMPILER_APPICON_NAME
=
AppIcon
;
INFOPLIST_FILE
=
ImageCard/Info.plist
;
LD_RUNPATH_SEARCH_PATHS
=
"$(inherited) @executable_path/Frameworks"
;
PRODUCT_BUNDLE_IDENTIFIER
=
io.cosmicmind.ImageCard
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
SWIFT_VERSION
=
3.0
;
};
name
=
Release
;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
9631A79F1D95ABB900CFB109
/* Build configuration list for PBXProject "ImageCard" */
=
{
isa
=
XCConfigurationList
;
buildConfigurations
=
(
9631A7B41D95ABB900CFB109
/* Debug */
,
9631A7B51D95ABB900CFB109
/* Release */
,
);
defaultConfigurationIsVisible
=
0
;
defaultConfigurationName
=
Release
;
};
9631A7B61D95ABB900CFB109
/* Build configuration list for PBXNativeTarget "ImageCard" */
=
{
isa
=
XCConfigurationList
;
buildConfigurations
=
(
9631A7B71D95ABB900CFB109
/* Debug */
,
9631A7B81D95ABB900CFB109
/* Release */
,
);
defaultConfigurationIsVisible
=
0
;
defaultConfigurationName
=
Release
;
};
/* End XCConfigurationList section */
};
rootObject
=
9631A79C1D95ABB900CFB109
/* Project object */
;
}
Examples/Programmatic/ImageCard/ImageCard.xcodeproj/project.xcworkspace/contents.xcworkspacedata
0 → 100644
View file @
52972dae
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version =
"1.0"
>
<FileRef
location =
"self:ImageCard.xcodeproj"
>
</FileRef>
</Workspace>
Examples/Programmatic/ImageCard/ImageCard/AppDelegate.swift
0 → 100644
View file @
52972dae
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import
UIKit
import
Material
@UIApplicationMain
class
AppDelegate
:
UIResponder
,
UIApplicationDelegate
{
var
window
:
UIWindow
?
func
applicationDidFinishLaunching
(
_
application
:
UIApplication
)
{
window
=
UIWindow
(
frame
:
Device
.
bounds
)
window
!.
rootViewController
=
ViewController
()
window
!.
makeKeyAndVisible
()
}
}
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/AppIcon.appiconset/Contents.json
0 → 100644
View file @
52972dae
{
"images"
:
[
{
"idiom"
:
"iphone"
,
"size"
:
"20x20"
,
"scale"
:
"2x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"20x20"
,
"scale"
:
"3x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"29x29"
,
"scale"
:
"2x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"29x29"
,
"scale"
:
"3x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"40x40"
,
"scale"
:
"2x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"40x40"
,
"scale"
:
"3x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"60x60"
,
"scale"
:
"2x"
},
{
"idiom"
:
"iphone"
,
"size"
:
"60x60"
,
"scale"
:
"3x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"20x20"
,
"scale"
:
"1x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"20x20"
,
"scale"
:
"2x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"29x29"
,
"scale"
:
"1x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"29x29"
,
"scale"
:
"2x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"40x40"
,
"scale"
:
"1x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"40x40"
,
"scale"
:
"2x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"76x76"
,
"scale"
:
"1x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"76x76"
,
"scale"
:
"2x"
},
{
"idiom"
:
"ipad"
,
"size"
:
"83.5x83.5"
,
"scale"
:
"2x"
}
],
"info"
:
{
"version"
:
1
,
"author"
:
"xcode"
}
}
\ No newline at end of file
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/Contents.json
0 → 100644
View file @
52972dae
{
"info"
:
{
"version"
:
1
,
"author"
:
"xcode"
}
}
\ No newline at end of file
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/CosmicMind.imageset/Contents.json
0 → 100644
View file @
52972dae
{
"images"
:
[
{
"idiom"
:
"universal"
,
"filename"
:
"CosmicMind.png"
,
"scale"
:
"1x"
},
{
"idiom"
:
"universal"
,
"scale"
:
"2x"
},
{
"idiom"
:
"universal"
,
"scale"
:
"3x"
}
],
"info"
:
{
"version"
:
1
,
"author"
:
"xcode"
}
}
\ No newline at end of file
Examples/Programmatic/ImageCard/ImageCard/Assets.xcassets/CosmicMind.imageset/CosmicMind.png
0 → 100644
View file @
52972dae
16.9 KB
Examples/Programmatic/ImageCard/ImageCard/Base.lproj/LaunchScreen.storyboard
0 → 100644
View file @
52972dae
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document
type=
"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB"
version=
"3.0"
toolsVersion=
"11134"
systemVersion=
"15F34"
targetRuntime=
"iOS.CocoaTouch"
propertyAccessControl=
"none"
useAutolayout=
"YES"
launchScreen=
"YES"
useTraitCollections=
"YES"
colorMatched=
"YES"
initialViewController=
"01J-lp-oVM"
>
<dependencies>
<plugIn
identifier=
"com.apple.InterfaceBuilder.IBCocoaTouchPlugin"
version=
"11106"
/>
<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"
>
<layoutGuides>
<viewControllerLayoutGuide
type=
"top"
id=
"Llm-lL-Icb"
/>
<viewControllerLayoutGuide
type=
"bottom"
id=
"xb3-aO-Qok"
/>
</layoutGuides>
<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"
/>
</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>
Examples/Programmatic/ImageCard/ImageCard/Info.plist
0 → 100644
View file @
52972dae
<
?xml
v
e
rsion="
1
.
0
"
e
n
c
o
d
ing="UT
F
-
8
"?
>
<
!
D
O
C
TYP
E
plist
PU
B
LI
C
"-//
A
ppl
e
//
D
T
D
PLIST
1
.
0
//
E
N"
"http://www.
a
ppl
e
.
c
om/
D
T
D
s/Prop
e
rtyList-
1
.
0
.
d
t
d
"
>
<
plist
v
e
rsion="
1
.
0
"
>
<
d
i
c
t
>
<
k
e
y
>
CFBundleDevelopmentRegion
<
/k
e
y
>
<
string
>
en
<
/string
>
<
k
e
y
>
CFBundleExecutable
<
/k
e
y
>
<
string
>
$
(
EXECUTABLE_NAME
)<
/string
>
<
k
e
y
>
CFBundleIdentifier
<
/k
e
y
>
<
string
>
$
(
PRODUCT_BUNDLE_IDENTIFIER
)<
/string
>
<
k
e
y
>
CFBundleInfoDictionaryVersion
<
/k
e
y
>
<
string
>
6.0
<
/string
>
<
k
e
y
>
CFBundleName
<
/k
e
y
>
<
string
>
$
(
PRODUCT_NAME
)<
/string
>
<
k
e
y
>
CFBundlePackageType
<
/k
e
y
>
<
string
>
APPL
<
/string
>
<
k
e
y
>
CFBundleShortVersionString
<
/k
e
y
>
<
string
>
1.0
<
/string
>
<
k
e
y
>
CFBundleVersion
<
/k
e
y
>
<
string
>
1
<
/string
>
<
k
e
y
>
LSRequiresIPhoneOS
<
/k
e
y
>
<
tru
e
/
>
<
k
e
y
>
UILaunchStoryboardName
<
/k
e
y
>
<
string
>
LaunchScreen
<
/string
>
<
k
e
y
>
UIRequiredDeviceCapabilities
<
/k
e
y
>
<
a
rr
a
y
>
<
string
>
armv7
<
/string
>
<
/
a
rr
a
y
>
<
k
e
y
>
UISupportedInterfaceOrientations
<
/k
e
y
>
<
a
rr
a
y
>
<
string
>
UIInterfaceOrientationPortrait
<
/string
>
<
string
>
UIInterfaceOrientationLandscapeLeft
<
/string
>
<
string
>
UIInterfaceOrientationLandscapeRight
<
/string
>
<
string
>
UIInterfaceOrientationPortraitUpsideDown
<
/string
>
<
/
a
rr
a
y
>
<
k
e
y
>
UISupportedInterfaceOrientations
~
ipad
<
/k
e
y
>
<
a
rr
a
y
>
<
string
>
UIInterfaceOrientationPortrait
<
/string
>
<
string
>
UIInterfaceOrientationPortraitUpsideDown
<
/string
>
<
string
>
UIInterfaceOrientationLandscapeLeft
<
/string
>
<
string
>
UIInterfaceOrientationLandscapeRight
<
/string
>
<
/
a
rr
a
y
>
<
/
d
i
c
t
>
<
/plist
>
Examples/Programmatic/ImageCard/ImageCard/ViewController.swift
0 → 100644
View file @
52972dae
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import
UIKit
import
Material
class
ViewController
:
UIViewController
{
private
var
imageView
:
UIImageView
!
private
var
toolbar
:
Toolbar
!
private
var
contentView
:
UILabel
!
private
var
bottomBar
:
Bar
!
private
var
favoriteButton
:
IconButton
!
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
view
.
backgroundColor
=
Color
.
grey
.
lighten5
prepareImageView
()
prepareToolbar
()
prepareContentView
()
prepareFavoriteButton
()
prepareBottomBar
()
prepareImageCard
()
}
private
func
prepareImageView
()
{
imageView
=
UIImageView
()
imageView
.
image
=
UIImage
(
named
:
"CosmicMind"
)
imageView
.
clipsToBounds
=
true
imageView
.
contentMode
=
.
scaleAspectFit
}
private
func
prepareToolbar
()
{
toolbar
=
Toolbar
()
toolbar
.
title
=
"Title"
toolbar
.
titleLabel
.
textAlignment
=
.
left
toolbar
.
detail
=
"Detail Description"
toolbar
.
detailLabel
.
textAlignment
=
.
left
toolbar
.
backgroundColor
=
nil
}
private
func
prepareContentView
()
{
contentView
=
UILabel
()
contentView
.
numberOfLines
=
0
contentView
.
text
=
"It’s been a while, have you read any new books lately?"
contentView
.
font
=
RobotoFont
.
regular
(
with
:
14
)
}
private
func
prepareFavoriteButton
()
{
favoriteButton
=
IconButton
(
image
:
Icon
.
favorite
,
tintColor
:
Color
.
blue
.
base
)
favoriteButton
.
pulseColor
=
Color
.
blue
.
base
}
private
func
prepareBottomBar
()
{
bottomBar
=
Bar
()
bottomBar
.
backgroundColor
=
nil
bottomBar
.
leftViews
=
[
favoriteButton
]
}
private
func
prepareImageCard
()
{
let
card
=
ImageCard
()
card
.
imageView
=
imageView
card
.
toolbar
=
toolbar
card
.
contentView
=
contentView
card
.
bottomBar
=
bottomBar
view
.
layout
(
card
)
.
top
(
100
)
.
left
(
20
)
.
right
(
20
)
}
}
Sources/iOS/Card.swift
View file @
52972dae
...
@@ -59,28 +59,9 @@ open class Card: PulseView {
...
@@ -59,28 +59,9 @@ open class Card: PulseView {
}
}
}
}
/// A preset wrapper around interimSpace.
/// A reference to the toolbar.
open
var
interimSpacePreset
=
InterimSpacePreset
.
none
{
didSet
{
interimSpace
=
InterimSpacePresetToValue
(
preset
:
interimSpacePreset
)
}
}
/// A wrapper around grid.interimSpace.
@IBInspectable
open
var
interimSpace
:
InterimSpace
{
get
{
return
grid
.
interimSpace
}
set
(
value
)
{
grid
.
interimSpace
=
value
layoutSubviews
()
}
}
/// A reference to the titleBar.
@IBInspectable
@IBInspectable
open
var
t
itleB
ar
:
Toolbar
?
{
open
var
t
oolb
ar
:
Toolbar
?
{
didSet
{
didSet
{
layoutSubviews
()
layoutSubviews
()
}
}
...
@@ -125,13 +106,13 @@ open class Card: PulseView {
...
@@ -125,13 +106,13 @@ open class Card: PulseView {
/**
/**
A convenience initiazlier.
A convenience initiazlier.
- Parameter t
itleB
ar: An optional Toolbar.
- Parameter t
oolb
ar: An optional Toolbar.
- Parameter contentView: An optional UIView.
- Parameter contentView: An optional UIView.
- Parameter bottomBar: An optional Bar.
- Parameter bottomBar: An optional Bar.
*/
*/
public
convenience
init
?(
t
itleB
ar
:
Toolbar
?,
contentView
:
UIView
?,
bottomBar
:
Bar
?)
{
public
convenience
init
?(
t
oolb
ar
:
Toolbar
?,
contentView
:
UIView
?,
bottomBar
:
Bar
?)
{
self
.
init
(
frame
:
.
zero
)
self
.
init
(
frame
:
.
zero
)
prepareProperties
(
t
itleBar
:
titleB
ar
,
contentView
:
contentView
,
bottomBar
:
bottomBar
)
prepareProperties
(
t
oolbar
:
toolb
ar
,
contentView
:
contentView
,
bottomBar
:
bottomBar
)
}
}
open
override
func
layoutSubviews
()
{
open
override
func
layoutSubviews
()
{
...
@@ -146,25 +127,30 @@ open class Card: PulseView {
...
@@ -146,25 +127,30 @@ open class Card: PulseView {
v
.
removeFromSuperview
()
v
.
removeFromSuperview
()
}
}
var
format
=
"V:|-(top)"
layout
()
}
/// Lays out view.
open
func
layout
()
{
var
format
=
"V:|"
var
views
=
[
String
:
Any
]()
var
views
=
[
String
:
Any
]()
if
let
v
=
t
itleB
ar
{
if
let
v
=
t
oolb
ar
{
format
+=
"
-[titleB
ar]"
format
+=
"
[toolb
ar]"
views
[
"t
itleB
ar"
]
=
v
views
[
"t
oolb
ar"
]
=
v
layout
(
v
)
.
horizontally
(
left
:
contentEdgeInsets
.
left
,
right
:
contentEdgeInsets
.
right
)
layout
(
v
)
.
horizontally
()
}
}
if
let
v
=
contentView
{
if
let
v
=
contentView
{
format
+=
(
nil
==
titleBar
?
""
:
"-(interimSpace)"
)
+
"-[contentView]
"
format
+=
"-(top)-[contentView]-(bottom)-
"
views
[
"contentView"
]
=
v
views
[
"contentView"
]
=
v
layout
(
v
)
.
horizontally
(
left
:
contentEdgeInsets
.
left
,
right
:
contentEdgeInsets
.
right
)
layout
(
v
)
.
horizontally
(
left
:
contentEdgeInsets
.
left
,
right
:
contentEdgeInsets
.
right
)
}
}
if
let
v
=
bottomBar
{
if
let
v
=
bottomBar
{
format
+=
(
nil
==
titleBar
&&
nil
==
contentView
?
""
:
"-(interimSpace)"
)
+
"-
[bottomBar]"
format
+=
"
[bottomBar]"
views
[
"bottomBar"
]
=
v
views
[
"bottomBar"
]
=
v
layout
(
v
)
.
horizontally
(
left
:
contentEdgeInsets
.
left
,
right
:
contentEdgeInsets
.
right
)
layout
(
v
)
.
horizontally
()
}
}
guard
0
<
views
.
count
else
{
guard
0
<
views
.
count
else
{
...
@@ -174,9 +160,8 @@ open class Card: PulseView {
...
@@ -174,9 +160,8 @@ open class Card: PulseView {
var
metrics
=
[
String
:
Any
]()
var
metrics
=
[
String
:
Any
]()
metrics
[
"top"
]
=
contentEdgeInsets
.
top
metrics
[
"top"
]
=
contentEdgeInsets
.
top
metrics
[
"bottom"
]
=
contentEdgeInsets
.
bottom
metrics
[
"bottom"
]
=
contentEdgeInsets
.
bottom
metrics
[
"interimSpace"
]
=
interimSpace
addConstraints
(
Layout
.
constraint
(
format
:
"
\(
format
)
-(bottom)-
|"
,
options
:
[],
metrics
:
metrics
,
views
:
views
))
addConstraints
(
Layout
.
constraint
(
format
:
"
\(
format
)
|"
,
options
:
[],
metrics
:
metrics
,
views
:
views
))
}
}
/**
/**
...
@@ -189,20 +174,17 @@ open class Card: PulseView {
...
@@ -189,20 +174,17 @@ open class Card: PulseView {
open
override
func
prepare
()
{
open
override
func
prepare
()
{
super
.
prepare
()
super
.
prepare
()
depthPreset
=
.
depth1
depthPreset
=
.
depth1
pulseAnimation
=
.
none
contentEdgeInsetsPreset
=
.
square1
interimSpacePreset
=
.
interimSpace3
cornerRadiusPreset
=
.
cornerRadius1
cornerRadiusPreset
=
.
cornerRadius1
}
}
/**
/**
A preparation method that sets the base UI elements.
A preparation method that sets the base UI elements.
- Parameter t
itleB
ar: An optional Toolbar.
- Parameter t
oolb
ar: An optional Toolbar.
- Parameter contentView: An optional UIView.
- Parameter contentView: An optional UIView.
- Parameter bottomBar: An optional Bar.
- Parameter bottomBar: An optional Bar.
*/
*/
internal
func
prepareProperties
(
t
itleB
ar
:
Toolbar
?,
contentView
:
UIView
?,
bottomBar
:
Bar
?)
{
internal
func
prepareProperties
(
t
oolb
ar
:
Toolbar
?,
contentView
:
UIView
?,
bottomBar
:
Bar
?)
{
self
.
t
itleBar
=
titleB
ar
self
.
t
oolbar
=
toolb
ar
self
.
contentView
=
contentView
self
.
contentView
=
contentView
self
.
bottomBar
=
bottomBar
self
.
bottomBar
=
bottomBar
}
}
...
...
Sources/iOS/ImageCard.swift
View file @
52972dae
...
@@ -30,558 +30,70 @@
...
@@ -30,558 +30,70 @@
import
UIKit
import
UIKit
open
class
ImageCard
:
PulseView
{
@objc(ToolbarAlignment)
/**
public
enum
ToolbarAlignment
:
Int
{
:name: dividerLayer
case
top
*/
case
bottom
private
var
dividerLayer
:
CAShapeLayer
?
}
/**
open
class
ImageCard
:
Card
{
:name: dividerColor
/// A reference to the imageView.
*/
@IBInspectable
@IBInspectable
open
var
imageView
:
UIImageView
?
{
open
var
dividerColor
:
UIColor
?
{
didSet
{
didSet
{
layoutSubviews
()
dividerLayer
?
.
backgroundColor
=
dividerColor
?
.
cgColor
}
}
}
}
/// An ImageCardToolbarAlignment value.
/**
open
var
toolbarAlignment
=
ToolbarAlignment
.
bottom
{
:name: divider
didSet
{
*/
layoutSubviews
()
@IBInspectable
open
var
divider
=
true
{
didSet
{
reloadView
()
}
}
/**
:name: dividerInsets
*/
open
var
dividerEdgeInsetsPreset
:
EdgeInsetsPreset
=
.
none
{
didSet
{
dividerInset
=
EdgeInsetsPresetToValue
(
preset
:
dividerEdgeInsetsPreset
)
}
}
/**
:name: dividerInset
*/
@IBInspectable
open
var
dividerInset
=
EdgeInsets
(
top
:
8
,
left
:
0
,
bottom
:
8
,
right
:
0
)
{
didSet
{
reloadView
()
}
}
/**
:name: imageLayer
*/
open
private(set)
var
imageLayer
:
CAShapeLayer
?
/**
:name: image
*/
@IBInspectable
open
override
var
image
:
UIImage
?
{
get
{
return
nil
==
imageLayer
?
.
contents
?
nil
:
UIImage
(
cgImage
:
imageLayer
?
.
contents
as!
CGImage
)
}
set
(
value
)
{
if
let
v
=
value
{
prepareImageLayer
()
imageLayer
?
.
contents
=
v
.
cgImage
if
0
==
maxImageHeight
{
imageLayer
?
.
height
=
image
!.
height
/
contentsScale
}
else
{
let
h
:
CGFloat
=
image
!.
height
/
contentsScale
imageLayer
?
.
height
=
maxImageHeight
<
h
?
maxImageHeight
:
h
}
imageLayer
?
.
isHidden
=
false
}
else
{
imageLayer
?
.
contents
=
nil
imageLayer
?
.
frame
=
.
zero
imageLayer
?
.
isHidden
=
true
imageLayer
?
.
removeFromSuperlayer
()
}
reloadView
()
}
}
/**
:name: maxImageHeight
*/
@IBInspectable
open
var
maxImageHeight
:
CGFloat
=
0
{
didSet
{
if
let
v
:
UIImage
=
image
{
if
0
<
maxImageHeight
{
prepareImageLayer
()
let
h
:
CGFloat
=
v
.
size
.
height
/
contentsScale
imageLayer
?
.
frame
.
size
.
height
=
maxImageHeight
<
h
?
maxImageHeight
:
h
}
else
{
maxImageHeight
=
0
imageLayer
?
.
frame
.
size
.
height
=
nil
==
image
?
0
:
v
.
size
.
height
/
contentsScale
}
reloadView
()
}
}
}
/**
:name: contentsRect
*/
@IBInspectable
open
override
var
contentsRect
:
CGRect
{
didSet
{
prepareImageLayer
()
imageLayer
?
.
contentsRect
=
contentsRect
}
}
/**
:name: contentsCenter
*/
@IBInspectable
open
override
var
contentsCenter
:
CGRect
{
didSet
{
prepareImageLayer
()
imageLayer
?
.
contentsCenter
=
contentsCenter
}
}
/**
:name: contentsScale
*/
@IBInspectable
open
override
var
contentsScale
:
CGFloat
{
didSet
{
prepareImageLayer
()
imageLayer
?
.
contentsScale
=
contentsScale
}
}
/// Determines how content should be aligned within the visualLayer's bounds.
@IBInspectable
open
override
var
contentsGravity
:
String
{
get
{
return
nil
==
imageLayer
?
""
:
imageLayer
!.
contentsGravity
}
set
(
value
)
{
prepareImageLayer
()
imageLayer
?
.
contentsGravity
=
value
}
}
/**
:name: contentInsets
*/
open
var
contentEdgeInsetsPreset
:
EdgeInsetsPreset
=
.
square2
{
didSet
{
contentInset
=
EdgeInsetsPresetToValue
(
preset
:
contentEdgeInsetsPreset
)
}
}
/**
:name: contentInset
*/
@IBInspectable
open
var
contentInset
=
EdgeInsetsPresetToValue
(
preset
:
.
square2
)
{
didSet
{
reloadView
()
}
}
/**
:name: titleLabelInsets
*/
open
var
titleLabelEdgeInsetsPreset
:
EdgeInsetsPreset
=
.
square2
{
didSet
{
titleLabelInset
=
EdgeInsetsPresetToValue
(
preset
:
titleLabelEdgeInsetsPreset
)
}
}
/**
:name: titleLabelInset
*/
@IBInspectable
open
var
titleLabelInset
=
EdgeInsetsPresetToValue
(
preset
:
.
square2
)
{
didSet
{
reloadView
()
}
}
/**
:name: titleLabel
*/
@IBInspectable
open
var
titleLabel
:
UILabel
?
{
didSet
{
reloadView
()
}
}
/**
:name: contentViewInsets
*/
open
var
contentViewEdgeInsetsPreset
:
EdgeInsetsPreset
=
.
square2
{
didSet
{
contentViewInset
=
EdgeInsetsPresetToValue
(
preset
:
contentViewEdgeInsetsPreset
)
}
}
/**
:name: contentViewInset
*/
@IBInspectable
open
var
contentViewInset
=
EdgeInsetsPresetToValue
(
preset
:
.
square2
)
{
didSet
{
reloadView
()
}
}
/**
:name: contentView
*/
@IBInspectable
open
var
contentView
:
UIView
?
{
didSet
{
reloadView
()
}
}
/**
:name: leftButtonsInsets
*/
open
var
leftButtonsEdgeInsetsPreset
:
EdgeInsetsPreset
=
.
none
{
didSet
{
leftButtonsInset
=
EdgeInsetsPresetToValue
(
preset
:
leftButtonsEdgeInsetsPreset
)
}
}
/**
:name: leftButtonsInset
*/
@IBInspectable
open
var
leftButtonsInset
=
EdgeInsets
.
zero
{
didSet
{
reloadView
()
}
}
/**
:name: leftButtons
*/
open
var
leftButtons
=
[
UIView
]()
{
didSet
{
reloadView
()
}
}
/**
:name: rightButtonsInsets
*/
open
var
rightButtonsEdgeInsetsPreset
:
EdgeInsetsPreset
=
.
none
{
didSet
{
rightButtonsInset
=
EdgeInsetsPresetToValue
(
preset
:
rightButtonsEdgeInsetsPreset
)
}
}
/**
:name: rightButtonsInset
*/
@IBInspectable
open
var
rightButtonsInset
=
EdgeInsets
.
zero
{
didSet
{
reloadView
()
}
}
/**
:name: rightButtons
*/
open
var
rightButtons
=
[
UIView
]()
{
didSet
{
reloadView
()
}
}
/**
:name: init
*/
public
required
init
?(
coder
aDecoder
:
NSCoder
)
{
super
.
init
(
coder
:
aDecoder
)
}
/**
:name: init
*/
public
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
}
/**
:name: init
*/
public
convenience
init
()
{
self
.
init
(
frame
:
.
zero
)
}
/**
:name: init
*/
public
convenience
init
?(
image
:
UIImage
?
=
nil
,
titleLabel
:
UILabel
?
=
nil
,
contentView
:
UIView
?
=
nil
,
leftButtons
:
[
UIView
]?
=
nil
,
rightButtons
:
[
UIView
]?
=
nil
)
{
self
.
init
(
frame
:
.
zero
)
prepareProperties
(
image
:
image
,
titleLabel
:
titleLabel
,
contentView
:
contentView
,
leftButtons
:
leftButtons
,
rightButtons
:
rightButtons
)
}
/**
:name: layoutSublayersOfLayer
*/
open
override
func
layoutSublayers
(
of
layer
:
CALayer
)
{
super
.
layoutSublayers
(
of
:
layer
)
if
self
.
layer
==
layer
{
// image
imageLayer
?
.
frame
.
size
.
width
=
bounds
.
width
// divider
if
divider
{
var
y
:
CGFloat
=
contentInset
.
bottom
+
dividerInset
.
bottom
if
0
<
leftButtons
.
count
{
y
+=
leftButtonsInset
.
top
+
leftButtonsInset
.
bottom
+
leftButtons
[
0
]
.
frame
.
height
}
else
if
0
<
rightButtons
.
count
{
y
+=
rightButtonsInset
.
top
+
rightButtonsInset
.
bottom
+
rightButtons
[
0
]
.
frame
.
height
}
if
0
<
y
{
prepareDivider
(
y
:
bounds
.
height
-
y
-
0.5
,
width
:
bounds
.
width
)
}
}
else
{
dividerLayer
?
.
removeFromSuperlayer
()
dividerLayer
=
nil
}
}
}
/**
:name: reloadView
*/
open
func
reloadView
()
{
// clear constraints so new ones do not conflict
removeConstraints
(
constraints
)
for
v
in
subviews
{
v
.
removeFromSuperview
()
}
var
verticalFormat
:
String
=
"V:|"
var
views
:
Dictionary
<
String
,
Any
>
=
Dictionary
<
String
,
Any
>
()
var
metrics
:
Dictionary
<
String
,
Any
>
=
Dictionary
<
String
,
Any
>
()
if
nil
!=
imageLayer
?
.
contents
{
verticalFormat
+=
"-(insetTop)"
metrics
[
"insetTop"
]
=
imageLayer
!.
frame
.
height
}
else
if
nil
!=
titleLabel
{
verticalFormat
+=
"-(insetTop)"
metrics
[
"insetTop"
]
=
contentInset
.
top
+
titleLabelInset
.
top
}
else
if
nil
!=
contentView
{
verticalFormat
+=
"-(insetTop)"
metrics
[
"insetTop"
]
=
contentInset
.
top
+
contentViewInset
.
top
}
// title
if
let
v
:
UILabel
=
titleLabel
{
if
nil
==
imageLayer
?
.
contents
{
verticalFormat
+=
"-[titleLabel]"
views
[
"titleLabel"
]
=
v
}
else
{
layout
(
v
)
.
top
(
contentInset
.
top
+
titleLabelInset
.
top
)
}
layout
(
v
)
.
horizontally
(
left
:
contentInset
.
left
+
titleLabelInset
.
left
,
right
:
contentInset
.
right
+
titleLabelInset
.
right
)
}
// detail
if
let
v
:
UIView
=
contentView
{
if
nil
==
imageLayer
?
.
contents
&&
nil
!=
titleLabel
{
verticalFormat
+=
"-(insetB)"
metrics
[
"insetB"
]
=
titleLabelInset
.
bottom
+
contentViewInset
.
top
}
else
{
metrics
[
"insetTop"
]
=
(
metrics
[
"insetTop"
]
as!
CGFloat
)
+
contentViewInset
.
top
}
verticalFormat
+=
"-[contentView]"
views
[
"contentView"
]
=
v
layout
(
v
)
.
horizontally
(
left
:
contentInset
.
left
+
contentViewInset
.
left
,
right
:
contentInset
.
right
+
contentViewInset
.
right
)
}
// leftButtons
if
0
<
leftButtons
.
count
{
var
h
:
String
=
"H:|"
var
d
:
Dictionary
<
String
,
Any
>
=
Dictionary
<
String
,
Any
>
()
var
i
:
Int
=
0
for
b
in
leftButtons
{
let
k
:
String
=
"b
\(
i
)
"
d
[
k
]
=
b
if
0
==
i
{
h
+=
"-(left)-"
}
else
{
h
+=
"-(left_right)-"
}
h
+=
"[
\(
k
)
]"
layout
(
b
)
.
bottom
(
contentInset
.
bottom
+
leftButtonsInset
.
bottom
)
i
+=
1
}
addConstraints
(
Layout
.
constraint
(
format
:
h
,
options
:
[],
metrics
:
[
"left"
:
contentInset
.
left
+
leftButtonsInset
.
left
,
"left_right"
:
leftButtonsInset
.
left
+
leftButtonsInset
.
right
],
views
:
d
))
}
}
}
// rightButtons
if
0
<
rightButtons
.
count
{
open
override
func
layout
()
{
var
h
:
String
=
"H:"
guard
let
iv
=
imageView
else
{
var
d
:
Dictionary
<
String
,
Any
>
=
Dictionary
<
String
,
Any
>
()
super
.
layout
()
var
i
:
Int
=
rightButtons
.
count
-
1
return
}
for
b
in
rightButtons
{
let
k
:
String
=
"b
\(
i
)
"
var
format
=
"V:|"
var
views
=
[
String
:
Any
]()
d
[
k
]
=
b
format
+=
"[imageView]"
h
+=
"[
\(
k
)
]"
views
[
"imageView"
]
=
iv
layout
(
iv
)
.
horizontally
()
if
0
==
i
{
h
+=
"-(right)-"
if
let
v
=
toolbar
{
}
else
{
iv
.
layout
(
v
)
.
horizontally
()
.
bottom
()
h
+=
"-(right_left)-"
if
.
top
==
toolbarAlignment
{
}
iv
.
layout
(
v
)
.
top
()
}
else
{
layout
(
b
)
.
bottom
(
contentInset
.
bottom
+
rightButtonsInset
.
bottom
)
iv
.
layout
(
v
)
.
bottom
()
i
-=
1
}
}
addConstraints
(
Layout
.
constraint
(
format
:
h
+
"|"
,
options
:
[],
metrics
:
[
"right"
:
contentInset
.
right
+
rightButtonsInset
.
right
,
"right_left"
:
rightButtonsInset
.
right
+
rightButtonsInset
.
left
],
views
:
d
))
}
}
if
nil
==
imageLayer
?
.
contents
{
if
let
v
=
contentView
{
if
0
<
leftButtons
.
count
{
format
+=
"-(top)-[contentView]-(bottom)-"
verticalFormat
+=
"-(insetC)-[button]"
views
[
"contentView"
]
=
v
views
[
"button"
]
=
leftButtons
[
0
]
layout
(
v
)
.
horizontally
(
left
:
contentEdgeInsets
.
left
,
right
:
contentEdgeInsets
.
right
)
metrics
[
"insetC"
]
=
leftButtonsInset
.
top
}
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
leftButtonsInset
.
bottom
}
else
if
0
<
rightButtons
.
count
{
if
let
v
=
bottomBar
{
verticalFormat
+=
"-(insetC)-[button]"
format
+=
"[bottomBar]"
views
[
"button"
]
=
rightButtons
[
0
]
views
[
"bottomBar"
]
=
v
metrics
[
"insetC"
]
=
rightButtonsInset
.
top
layout
(
v
)
.
horizontally
()
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
rightButtonsInset
.
bottom
}
}
guard
0
<
views
.
count
else
{
if
nil
!=
contentView
{
return
if
nil
==
metrics
[
"insetC"
]
{
}
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
contentViewInset
.
bottom
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
}
else
{
var
metrics
=
[
String
:
Any
]()
metrics
[
"insetC"
]
=
(
metrics
[
"insetC"
]
as!
CGFloat
)
+
contentViewInset
.
bottom
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
metrics
[
"top"
]
=
contentEdgeInsets
.
top
}
metrics
[
"bottom"
]
=
contentEdgeInsets
.
bottom
}
else
if
nil
!=
titleLabel
{
if
nil
==
metrics
[
"insetC"
]
{
addConstraints
(
Layout
.
constraint
(
format
:
"
\(
format
)
|"
,
options
:
[],
metrics
:
metrics
,
views
:
views
))
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
titleLabelInset
.
bottom
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
}
}
else
{
metrics
[
"insetC"
]
=
(
metrics
[
"insetC"
]
as!
CGFloat
)
+
titleLabelInset
.
bottom
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
}
}
else
if
nil
!=
metrics
[
"insetC"
]
{
metrics
[
"insetC"
]
=
(
metrics
[
"insetC"
]
as!
CGFloat
)
+
contentInset
.
top
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
}
}
else
if
nil
!=
contentView
{
if
0
<
leftButtons
.
count
{
verticalFormat
+=
"-(insetC)-[button]"
views
[
"button"
]
=
leftButtons
[
0
]
metrics
[
"insetC"
]
=
leftButtonsInset
.
top
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
leftButtonsInset
.
bottom
}
else
if
0
<
rightButtons
.
count
{
verticalFormat
+=
"-(insetC)-[button]"
views
[
"button"
]
=
rightButtons
[
0
]
metrics
[
"insetC"
]
=
rightButtonsInset
.
top
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
rightButtonsInset
.
bottom
}
if
nil
==
metrics
[
"insetC"
]
{
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
contentViewInset
.
bottom
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
}
else
{
metrics
[
"insetC"
]
=
(
metrics
[
"insetC"
]
as!
CGFloat
)
+
contentViewInset
.
bottom
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
}
}
else
{
if
0
<
leftButtons
.
count
{
verticalFormat
+=
"-[button]"
views
[
"button"
]
=
leftButtons
[
0
]
metrics
[
"insetTop"
]
=
(
metrics
[
"insetTop"
]
as!
CGFloat
)
+
contentInset
.
top
+
leftButtonsInset
.
top
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
leftButtonsInset
.
bottom
}
else
if
0
<
rightButtons
.
count
{
verticalFormat
+=
"-[button]"
views
[
"button"
]
=
rightButtons
[
0
]
metrics
[
"insetTop"
]
=
(
metrics
[
"insetTop"
]
as!
CGFloat
)
+
contentInset
.
top
+
rightButtonsInset
.
top
+
(
divider
?
dividerInset
.
top
+
dividerInset
.
bottom
:
0
)
metrics
[
"insetBottom"
]
=
contentInset
.
bottom
+
rightButtonsInset
.
bottom
}
else
{
if
translatesAutoresizingMaskIntoConstraints
{
addConstraints
(
Layout
.
constraint
(
format
:
"V:[view(height)]"
,
options
:
[],
metrics
:
[
"height"
:
imageLayer
!.
frame
.
height
],
views
:
[
"view"
:
self
]))
}
else
{
height
=
imageLayer
!.
frame
.
height
}
}
}
if
0
<
views
.
count
{
verticalFormat
+=
"-(insetBottom)-|"
addConstraints
(
Layout
.
constraint
(
format
:
verticalFormat
,
options
:
[],
metrics
:
metrics
,
views
:
views
))
}
}
/**
:name: prepare
*/
open
override
func
prepare
()
{
super
.
prepare
()
depthPreset
=
.
depth1
dividerColor
=
Color
.
grey
.
lighten3
cornerRadiusPreset
=
.
cornerRadius1
}
/**
:name: prepareImageLayer
*/
internal
func
prepareImageLayer
()
{
if
nil
==
imageLayer
{
imageLayer
=
CAShapeLayer
()
imageLayer
!.
masksToBounds
=
true
imageLayer
!.
zPosition
=
0
visualLayer
.
addSublayer
(
imageLayer
!
)
}
}
/**
:name: prepareDivider
*/
internal
func
prepareDivider
(
y
:
CGFloat
,
width
:
CGFloat
)
{
if
nil
==
dividerLayer
{
dividerLayer
=
CAShapeLayer
()
dividerLayer
!.
zPosition
=
0
layer
.
addSublayer
(
dividerLayer
!
)
}
dividerLayer
?
.
backgroundColor
=
dividerColor
?
.
cgColor
dividerLayer
?
.
frame
=
CGRect
(
x
:
dividerInset
.
left
,
y
:
y
,
width
:
width
-
dividerInset
.
left
-
dividerInset
.
right
,
height
:
1
)
}
/**
:name: prepareProperties
*/
internal
func
prepareProperties
(
image
:
UIImage
?,
titleLabel
:
UILabel
?,
contentView
:
UIView
?,
leftButtons
:
[
UIView
]?,
rightButtons
:
[
UIView
]?)
{
self
.
image
=
image
self
.
titleLabel
=
titleLabel
self
.
contentView
=
contentView
self
.
leftButtons
=
leftButtons
??
[]
self
.
rightButtons
=
rightButtons
??
[]
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment