Commit e773c782 by Daniel Dahan

storyboard-examples: preparation for 2.1.1 release

parent f1c4b4d9
......@@ -36,7 +36,6 @@ class RootViewController: UIViewController {
private var menuButton: IconButton!
private var starButton: IconButton!
private var searchButton: IconButton!
private var switchControl: Switch!
/// Trigger to go to the next view controller.
private var nextButton: FlatButton!
......@@ -78,9 +77,7 @@ class RootViewController: UIViewController {
navigationItem.detail = "Build Beautiful Software"
navigationItem.detailLabel.textColor = Color.lightBlue.lighten5
switchControl = Switch()
navigationItem.leftViews = [switchControl, menuButton]
navigationItem.leftViews = [menuButton]
navigationItem.rightViews = [starButton, searchButton]
}
......
......@@ -14,6 +14,7 @@
96784E8C1D8FFEA20061C06C /* LeftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784E8B1D8FFEA10061C06C /* LeftViewController.swift */; };
96784E8E1D8FFEC80061C06C /* RightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784E8D1D8FFEC80061C06C /* RightViewController.swift */; };
96784E901D8FFEEF0061C06C /* AppNavigationDrawerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784E8F1D8FFEEF0061C06C /* AppNavigationDrawerController.swift */; };
968948791DA995C400DA9FD9 /* AppToolbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 968948781DA995C400DA9FD9 /* AppToolbarController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
......@@ -39,6 +40,7 @@
96784E8B1D8FFEA10061C06C /* LeftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftViewController.swift; sourceTree = "<group>"; };
96784E8D1D8FFEC80061C06C /* RightViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RightViewController.swift; sourceTree = "<group>"; };
96784E8F1D8FFEEF0061C06C /* AppNavigationDrawerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNavigationDrawerController.swift; sourceTree = "<group>"; };
968948781DA995C400DA9FD9 /* AppToolbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppToolbarController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -73,6 +75,7 @@
children = (
96784E761D8FFE230061C06C /* AppDelegate.swift */,
96784E8F1D8FFEEF0061C06C /* AppNavigationDrawerController.swift */,
968948781DA995C400DA9FD9 /* AppToolbarController.swift */,
96784E781D8FFE230061C06C /* RootViewController.swift */,
96784E8B1D8FFEA10061C06C /* LeftViewController.swift */,
96784E8D1D8FFEC80061C06C /* RightViewController.swift */,
......@@ -156,6 +159,7 @@
buildActionMask = 2147483647;
files = (
96784E8C1D8FFEA20061C06C /* LeftViewController.swift in Sources */,
968948791DA995C400DA9FD9 /* AppToolbarController.swift in Sources */,
96784E8E1D8FFEC80061C06C /* RightViewController.swift in Sources */,
96784E901D8FFEEF0061C06C /* AppNavigationDrawerController.swift in Sources */,
96784E791D8FFE230061C06C /* RootViewController.swift in Sources */,
......
......@@ -37,8 +37,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func applicationDidFinishLaunching(_ application: UIApplication) {
let appToolbarController = AppToolbarController(rootViewController: RootViewController())
let leftViewController = LeftViewController()
let rightViewController = RightViewController()
window = UIWindow(frame: Device.bounds)
window!.rootViewController = AppNavigationDrawerController(rootViewController: RootViewController(), leftViewController: LeftViewController(), rightViewController: RightViewController())
window!.rootViewController = AppNavigationDrawerController(rootViewController: appToolbarController, leftViewController: leftViewController, rightViewController: rightViewController)
window!.makeKeyAndVisible()
}
}
......
/*
* 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 AppToolbarController: ToolbarController {
open override func prepare() {
super.prepare()
statusBarStyle = .default
}
}
......@@ -32,8 +32,62 @@ import UIKit
import Material
class RootViewController: UIViewController {
/// Toolbar buttons.
private var menuButton: IconButton!
private var switchControl: Switch!
private var moreButton: IconButton!
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.white
}
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
prepareMenuButton()
prepareSwitch()
prepareMoreButton()
prepareToolbar()
}
@objc
internal func handleMenuButton() {
navigationDrawerController?.toggleLeftView()
}
@objc
internal func handleMoreButton() {
navigationDrawerController?.toggleRightView()
}
private func prepareMenuButton() {
menuButton = IconButton(image: Icon.cm.menu, tintColor: Color.blue.base)
menuButton.addTarget(self, action: #selector(handleMenuButton), for: .touchUpInside)
}
private func prepareSwitch() {
switchControl = Switch(state: .off, style: .light, size: .small)
}
private func prepareMoreButton() {
moreButton = IconButton(image: Icon.cm.moreVertical, tintColor: Color.blue.base)
moreButton.addTarget(self, action: #selector(handleMoreButton), for: .touchUpInside)
}
private func prepareToolbar() {
guard let tc = toolbarController else {
return
}
tc.toolbar.title = "Marterial"
// tc.toolbar.titleLabel.textAlignment = .left
tc.toolbar.detail = "Build Beautiful Software"
// tc.toolbar.detailLabel.textAlignment = .left
tc.toolbar.leftViews = [menuButton]
tc.toolbar.rightViews = [switchControl, moreButton]
}
}
......@@ -47,8 +47,7 @@ class BlueViewController: UIViewController {
view.backgroundColor = Color.blue.base
}
/// Prepares the pageTabBarItem.
internal func preparePageTabBarItem() {
private func preparePageTabBarItem() {
pageTabBarItem.title = "Blue"
pageTabBarItem.titleColor = Color.blueGrey.base
}
......
......@@ -47,8 +47,7 @@ class GreenViewController: UIViewController {
view.backgroundColor = Color.green.base
}
/// Prepares the pageTabBarItem.
internal func preparePageTabBarItem() {
private func preparePageTabBarItem() {
pageTabBarItem.title = "Green"
pageTabBarItem.titleColor = Color.blueGrey.base
}
......
......@@ -47,8 +47,7 @@ class RedViewController: UIViewController {
view.backgroundColor = Color.red.base
}
/// Prepares the pageTabBarItem.
internal func preparePageTabBarItem() {
private func preparePageTabBarItem() {
pageTabBarItem.title = "Red"
pageTabBarItem.titleColor = Color.blueGrey.base
}
......
......@@ -32,7 +32,6 @@ import UIKit
import Material
class RootViewController: UIViewController {
/// SearchBar buttons.
private var menuButton: IconButton!
private var moreButton: IconButton!
......
......@@ -32,27 +32,26 @@ import UIKit
import Material
class RootViewController: UIViewController {
/// A reference to the Undo button.
private var undoButton: FlatButton!
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.white
prepareUndoButton()
view.backgroundColor = Color.grey.lighten5
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
prepareUndoButton()
prepareSnackbar()
animateSnackbar()
scheduleAnimation()
}
private func prepareUndoButton() {
undoButton = FlatButton(title: "Undo", titleColor: Color.yellow.base)
undoButton.pulseAnimation = .backing
undoButton.titleLabel?.font = RobotoFont.regular(with: 14)
undoButton.titleLabel?.font = snackbarController?.snackbar.textLabel.font
}
private func prepareSnackbar() {
......@@ -64,6 +63,11 @@ class RootViewController: UIViewController {
sc.snackbar.rightViews = [undoButton]
}
private func scheduleAnimation() {
_ = Timer.scheduledTimer(timeInterval: 6, target: self, selector: #selector(animateSnackbar), userInfo: nil, repeats: true)
}
@objc
private func animateSnackbar() {
guard let sc = snackbarController else {
return
......
......@@ -294,7 +294,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = BottomNavigationController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.BottomNavigationController;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.BottomNavigationController;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......@@ -306,7 +306,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = BottomNavigationController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.BottomNavigationController;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.BottomNavigationController;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......
......@@ -37,15 +37,14 @@ class AudioViewController: UIViewController {
prepareTabBarItem()
}
/// Prepare tabBarItem.
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.blue.base
}
private func prepareTabBarItem() {
tabBarItem.title = nil
tabBarItem.image = Icon.cm.audioLibrary?.tintWithColor(color: Color.blueGrey.base)?.withRenderingMode(.alwaysOriginal)
tabBarItem.selectedImage = Icon.cm.audioLibrary?.tintWithColor(color: Color.blue.base)?.withRenderingMode(.alwaysOriginal)
}
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.blue.base
}
}
......@@ -33,6 +33,7 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>
......@@ -37,15 +37,14 @@ class PhotoViewController: UIViewController {
prepareTabBarItem()
}
/// Prepare tabBarItem.
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.red.base
}
private func prepareTabBarItem() {
tabBarItem.title = nil
tabBarItem.image = Icon.cm.photoCamera?.tintWithColor(color: Color.blueGrey.base)?.withRenderingMode(.alwaysOriginal)
tabBarItem.selectedImage = Icon.cm.photoCamera?.tintWithColor(color: Color.blue.base)?.withRenderingMode(.alwaysOriginal)
}
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.red.base
}
}
......@@ -37,15 +37,14 @@ class RemindersViewController: UIViewController {
prepareTabBarItem()
}
/// Prepare tabBarItem.
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.yellow.base
}
private func prepareTabBarItem() {
tabBarItem.title = nil
tabBarItem.image = Icon.cm.bell?.tintWithColor(color: Color.blueGrey.base)?.withRenderingMode(.alwaysOriginal)
tabBarItem.selectedImage = Icon.cm.bell?.tintWithColor(color: Color.blue.base)?.withRenderingMode(.alwaysOriginal)
}
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.yellow.base
}
}
......@@ -37,15 +37,14 @@ class SearchViewController: UIViewController {
prepareTabBarItem()
}
/// Prepare tabBarItem.
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.blueGrey.base
}
private func prepareTabBarItem() {
tabBarItem.title = nil
tabBarItem.image = Icon.cm.search?.tintWithColor(color: Color.blueGrey.base)?.withRenderingMode(.alwaysOriginal)
tabBarItem.selectedImage = Icon.cm.search?.tintWithColor(color: Color.blue.base)?.withRenderingMode(.alwaysOriginal)
}
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.blueGrey.base
}
}
......@@ -37,15 +37,14 @@ class VideoViewController: UIViewController {
prepareTabBarItem()
}
/// Prepare tabBarItem.
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.green.base
}
private func prepareTabBarItem() {
tabBarItem.title = nil
tabBarItem.image = Icon.cm.videocam?.tintWithColor(color: Color.blueGrey.base)?.withRenderingMode(.alwaysOriginal)
tabBarItem.selectedImage = Icon.cm.videocam?.tintWithColor(color: Color.blue.base)?.withRenderingMode(.alwaysOriginal)
}
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.green.base
}
}
......@@ -275,7 +275,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Button/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.Button;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.Button;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......@@ -288,7 +288,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Button/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.Button;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.Button;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......
......@@ -34,6 +34,5 @@ import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
}
......@@ -33,6 +33,7 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>
......@@ -7,12 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
9689485C1DA97CD400DA9FD9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9689485B1DA97CD400DA9FD9 /* Main.storyboard */; };
96CC49CD1D8DD984002CAB55 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC49CC1D8DD984002CAB55 /* AppDelegate.swift */; };
96CC49CF1D8DD984002CAB55 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC49CE1D8DD984002CAB55 /* RootViewController.swift */; };
96CC49D41D8DD984002CAB55 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96CC49D31D8DD984002CAB55 /* Assets.xcassets */; };
96CC49D71D8DD984002CAB55 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96CC49D51D8DD984002CAB55 /* LaunchScreen.storyboard */; };
96CC49E51D8DDF61002CAB55 /* NextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC49E41D8DDF61002CAB55 /* NextViewController.swift */; };
9A5634E11D9EF705004BFC00 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A5634E01D9EF705004BFC00 /* Main.storyboard */; };
9A5634E61D9EF9A7004BFC00 /* AppNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5634E51D9EF9A7004BFC00 /* AppNavigationController.swift */; };
/* End PBXBuildFile section */
......@@ -30,6 +30,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9689485B1DA97CD400DA9FD9 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
96CC49C91D8DD984002CAB55 /* NavigationController.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NavigationController.app; sourceTree = BUILT_PRODUCTS_DIR; };
96CC49CC1D8DD984002CAB55 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
96CC49CE1D8DD984002CAB55 /* RootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = "<group>"; };
......@@ -37,7 +38,6 @@
96CC49D61D8DD984002CAB55 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
96CC49D81D8DD984002CAB55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
96CC49E41D8DDF61002CAB55 /* NextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NextViewController.swift; sourceTree = "<group>"; };
9A5634E01D9EF705004BFC00 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
9A5634E51D9EF9A7004BFC00 /* AppNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNavigationController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -75,10 +75,10 @@
9A5634E51D9EF9A7004BFC00 /* AppNavigationController.swift */,
96CC49CE1D8DD984002CAB55 /* RootViewController.swift */,
96CC49E41D8DDF61002CAB55 /* NextViewController.swift */,
9689485B1DA97CD400DA9FD9 /* Main.storyboard */,
96CC49D31D8DD984002CAB55 /* Assets.xcassets */,
96CC49D51D8DD984002CAB55 /* LaunchScreen.storyboard */,
96CC49D81D8DD984002CAB55 /* Info.plist */,
9A5634E01D9EF705004BFC00 /* Main.storyboard */,
);
path = NavigationController;
sourceTree = "<group>";
......@@ -143,7 +143,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9A5634E11D9EF705004BFC00 /* Main.storyboard in Resources */,
9689485C1DA97CD400DA9FD9 /* Main.storyboard in Resources */,
96CC49D71D8DD984002CAB55 /* LaunchScreen.storyboard in Resources */,
96CC49D41D8DD984002CAB55 /* Assets.xcassets in Resources */,
);
......
......@@ -20,10 +20,10 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>Main</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
......
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="O4j-jr-GhC">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A313a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="O4j-jr-GhC">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
......@@ -28,9 +28,9 @@
<!--App Navigation Controller-->
<scene sceneID="uvK-GO-nSj">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="O4j-jr-GhC" customClass="AppNavigationController" customModule="Material" sceneMemberID="viewController">
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="O4j-jr-GhC" customClass="AppNavigationController" customModule="NavigationController" customModuleProvider="target" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" id="ruX-44-ffD">
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" id="ruX-44-ffD" customClass="NavigationBar" customModule="Material">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
......
......@@ -77,7 +77,6 @@ class RootViewController: UIViewController {
private func prepareNextButton() {
nextButton = FlatButton()
nextButton.pulseAnimation = .none
nextButton.addTarget(self, action: #selector(handleNextButton), for: .touchUpInside)
view.layout(nextButton).edges()
}
......
......@@ -286,7 +286,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = NavigationDrawerController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.NavigationDrawerController;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.NavigationDrawerController;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......@@ -298,7 +298,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = NavigationDrawerController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.NavigationDrawerController;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.NavigationDrawerController;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......
......@@ -33,6 +33,7 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>
......@@ -286,7 +286,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = PageTabBarController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.PageTabBarController;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.PageTabBarController;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......@@ -298,7 +298,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = PageTabBarController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cosmicmind.PageTabBarController;
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.PageTabBarController;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
......
......@@ -53,11 +53,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return UIStoryboard.viewController(identifier: "RedViewController") as! RedViewController
}()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
func applicationDidFinishLaunching(_ application: UIApplication) {
window = UIWindow(frame: UIScreen.main.bounds)
window!.rootViewController = AppPageTabBarController(viewControllers: [redViewController, greenViewController, blueViewController], selectedIndex: 0)
window!.makeKeyAndVisible()
return true
}
}
......@@ -39,7 +39,6 @@ class AppPageTabBarController: PageTabBarController {
preparePageTabBar()
}
/// Prepares the pageTabBar.
private func preparePageTabBar() {
pageTabBar.lineColor = Color.grey.darken1
}
......
......@@ -47,8 +47,7 @@ class BlueViewController: UIViewController {
view.backgroundColor = Color.blue.base
}
/// Prepares the pageTabBarItem.
internal func preparePageTabBarItem() {
private func preparePageTabBarItem() {
pageTabBarItem.title = "Blue"
pageTabBarItem.titleColor = Color.blueGrey.base
}
......
......@@ -47,8 +47,7 @@ class GreenViewController: UIViewController {
view.backgroundColor = Color.green.base
}
/// Prepares the pageTabBarItem.
internal func preparePageTabBarItem() {
private func preparePageTabBarItem() {
pageTabBarItem.title = "Green"
pageTabBarItem.titleColor = Color.blueGrey.base
}
......
......@@ -33,6 +33,7 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>
......@@ -47,8 +47,7 @@ class RedViewController: UIViewController {
view.backgroundColor = Color.red.base
}
/// Prepares the pageTabBarItem.
internal func preparePageTabBarItem() {
private func preparePageTabBarItem() {
pageTabBarItem.title = "Red"
pageTabBarItem.titleColor = Color.blueGrey.base
}
......
......@@ -72,10 +72,10 @@
96784EC51D9012980061C06C /* AppDelegate.swift */,
96784F231D901E7D0061C06C /* AppSearchBarController.swift */,
96784EC71D9012980061C06C /* RootViewController.swift */,
9AC456331D9DE1F900A7ABF0 /* Main.storyboard */,
96784ECC1D9012980061C06C /* Assets.xcassets */,
96784ECE1D9012980061C06C /* LaunchScreen.storyboard */,
96784ED11D9012980061C06C /* Info.plist */,
9AC456331D9DE1F900A7ABF0 /* Main.storyboard */,
);
path = SearchBarController;
sourceTree = "<group>";
......
......@@ -32,7 +32,6 @@ import UIKit
import Material
class RootViewController: UIViewController {
/// SearchBar buttons.
private var menuButton: IconButton!
private var moreButton: IconButton!
......
......@@ -32,27 +32,26 @@ import UIKit
import Material
class RootViewController: UIViewController {
/// A reference to the Undo button.
private var undoButton: FlatButton!
open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.grey.lighten5
prepareUndoButton()
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
prepareUndoButton()
prepareSnackbar()
animateSnackbar()
scheduleAnimation()
}
private func prepareUndoButton() {
undoButton = FlatButton(title: "Undo", titleColor: Color.yellow.base)
undoButton.pulseAnimation = .backing
undoButton.titleLabel?.font = RobotoFont.regular(with: 14)
undoButton.titleLabel?.font = snackbarController?.snackbar.textLabel.font
}
private func prepareSnackbar() {
......@@ -65,10 +64,11 @@ class RootViewController: UIViewController {
}
private func scheduleAnimation() {
_ = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.animateSnackbar), userInfo: nil, repeats: true)
_ = Timer.scheduledTimer(timeInterval: 6, target: self, selector: #selector(animateSnackbar), userInfo: nil, repeats: true)
}
@objc private func animateSnackbar() {
@objc
private func animateSnackbar() {
guard let sc = snackbarController else {
return
}
......
......@@ -72,10 +72,10 @@
96784EE31D9012B00061C06C /* AppDelegate.swift */,
96784F191D901DEF0061C06C /* AppStatusBarController.swift */,
96784EE51D9012B00061C06C /* RootViewController.swift */,
9AC456311D9DE0B300A7ABF0 /* Main.storyboard */,
96784EEA1D9012B00061C06C /* Assets.xcassets */,
96784EEC1D9012B10061C06C /* LaunchScreen.storyboard */,
96784EEF1D9012B10061C06C /* Info.plist */,
9AC456311D9DE0B300A7ABF0 /* Main.storyboard */,
);
path = StatusBarController;
sourceTree = "<group>";
......
Pod::Spec.new do |s|
s.name = 'Material'
s.version = '2.1.0'
s.version = '2.1.1'
s.license = 'BSD-3-Clause'
s.summary = 'Material is an animation and graphics framework that is used to create beautiful applications.'
s.homepage = 'http://cosmicmind.io'
......
......@@ -81,13 +81,23 @@ Icons is a library of Google and CosmicMind icons that are available for use wit
![Icon](http://www.cosmicmind.io/MK/MaterialMaterialIcon.png)
[Learn More](http://cosmicmind.io/material/icons)
## Colors
Try the Material Colors app to see the wonderful colors available in Material, or use the online version at [materialColors.io](http://materialcolors.io)
![MaterialColors](http://www.cosmicmind.io/gifs/MaterialColors.gif)
[Get Material Colors on the AppStore](https://itunes.apple.com/app/x/id1111994400?mt=8)
## TextField
A TextField is an excellent way to improve UX. It allows for a placeholder and additional hint details.
![TextField](http://www.cosmicmind.io/gifs/TextField.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/TextField)
[Learn More](http://cosmicmind.io/material/textfield)
## Button
......@@ -95,7 +105,7 @@ A button is used to trigger an action through a touch event. Material comes with
![Material Image](http://www.cosmicmind.io/material/white/button.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/Button)
[Learn More](http://cosmicmind.io/material/button)
## Switch
......@@ -103,7 +113,7 @@ A switch is a control component that toggles between on and off states.
![Material Image](http://www.cosmicmind.io/material/white/switch.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/Switch)
[Learn More](http://cosmicmind.io/material/switch)
## Card
......@@ -111,7 +121,7 @@ A Card is a flexible component that may be configured in any way you like. It ha
![Material Image](http://www.cosmicmind.io/material/white/card.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/Card)
[Learn More](http://cosmicmind.io/material/card)
## ImageCard
......@@ -119,7 +129,7 @@ An ImageCard is an expansion of the base Card. The Toolbar overlays an image are
![Material Image](http://www.cosmicmind.io/material/white/image-card.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/ImageCard)
[Learn More](http://cosmicmind.io/material/imagecard)
## PresenterCard
......@@ -127,7 +137,7 @@ The PresenterCard is a completely new card style. It allows for a primary presen
![Material Image](http://www.cosmicmind.io/material/white/presenter-card.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/PresenterCard)
[Learn More](http://cosmicmind.io/material/presentercard)
## Menu
......@@ -135,7 +145,7 @@ A Menu manages a collection of views. A new MenuItem type has been added that ma
![Material Image](http://www.cosmicmind.io/material/white/menu-controller.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/MenuController)
[Learn More](http://cosmicmind.io/material/menu)
## Toolbar
......@@ -143,7 +153,7 @@ Toolbars are super flexible and add excellent control to your navigation flow. T
![Material Image](http://www.cosmicmind.io/gifs/Toolbar.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/ToolbarController)
[Learn More](http://cosmicmind.io/material/toolbar)
## SearchBar
......@@ -151,7 +161,7 @@ A SearchBar is a powerful navigation tool that allows for user's input with an i
![Material Image](http://www.cosmicmind.io/gifs/SearchBar.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/SearchBarController)
[Learn More](http://cosmicmind.io/material/searchbar)
## PageTabBar
......@@ -159,7 +169,23 @@ A PageTabBar is a new component that links a customizable TabBar to a UIPageView
![Material Image](http://www.cosmicmind.io/material/white/page-tab-bar-controller.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/PageTabBarController)
[Learn More](http://cosmicmind.io/material/pagetabbar)
## NavigationController
A NavigationController is a specialized view controller that manages a hierarchy of content efficiently, making it easier for users to move within an application.
![Material Image](http://www.cosmicmind.io/material/white/navigation-controller.gif)
[Learn More](http://cosmicmind.io/material/navigationcontroller)
## NavigationDrawer
A NavigationDrawer slides in from the left or right and contains the navigation destinations for your application.
![Material Image](http://www.cosmicmind.io/material/shared/navigation-drawer-controller.gif)
[Learn More](http://cosmicmind.io/material/navigationdrawer)
## Snackbar
......@@ -167,7 +193,7 @@ A Snackbar is a new component that is very simple in its behavior and very power
![Material Image](http://www.cosmicmind.io/material/white/snackbar-controller.gif)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/SnackbarController)
[Learn More](http://cosmicmind.io/material/snackbar)
## PhotoLibrary
......@@ -175,7 +201,7 @@ PhotoLibrary is a new component that simplifies the Photos framework and allows
![Material Image](http://www.cosmicmind.io/material/shared/photolibrary-controller.png)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/PhotoLibraryController)
[Learn More](http://cosmicmind.io/material/photolibrary)
## Capture
......@@ -183,7 +209,7 @@ Capture is an API that simplifies iOS' AVFoundation framework. It allows for pho
![Material Image](http://www.cosmicmind.io/material/shared/capture-controller.png)
[Example Project](https://github.com/CosmicMind/Material/tree/development/Examples/Programmatic/CaptureController)
[Learn More](http://cosmicmind.io/material/capture)
## Sticker Sheet
......@@ -193,14 +219,6 @@ To help template your project, checkout Material Sticker Sheet.
[Get Material Sticker Sheet](http://www.materialup.com/posts/material-design-sticker-sheets)
## Material Colors
Try the Material Colors app to see the wonderful colors available in Material, or use the online version at [materialColors.io](http://materialcolors.io)
![MaterialColors](http://www.cosmicmind.io/gifs/MaterialColors.gif)
[Get Material Colors on the AppStore](https://itunes.apple.com/app/x/id1111994400?mt=8)
## Much More...
So much more inside. Enjoy!
......
......@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.1.0</string>
<string>2.1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
......
......@@ -171,7 +171,6 @@ open class Bar: View {
self.centerViews = centerViews ?? []
frame.size = intrinsicContentSize
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
......@@ -190,10 +189,14 @@ open class Bar: View {
grid.axis.columns = columns
for v in leftViews {
(v as? UIButton)?.contentEdgeInsets = .zero
if let b = v as? UIButton {
b.contentEdgeInsets = .zero
b.titleEdgeInsets = .zero
}
v.width = v.intrinsicContentSize.width
v.sizeToFit()
v.grid.columns = Int(ceil(v.width / gridFactor)) + 1
v.grid.columns = Int(ceil(v.width / gridFactor)) + 2
lc += v.grid.columns
......@@ -203,10 +206,14 @@ open class Bar: View {
grid.views.append(contentView)
for v in rightViews {
(v as? UIButton)?.contentEdgeInsets = .zero
if let b = v as? UIButton {
b.contentEdgeInsets = .zero
b.titleEdgeInsets = .zero
}
v.width = v.intrinsicContentSize.width
v.sizeToFit()
v.grid.columns = Int(ceil(v.width / gridFactor)) + 1
v.grid.columns = Int(ceil(v.width / gridFactor)) + 2
rc += v.grid.columns
......@@ -244,8 +251,8 @@ open class Bar: View {
open override func prepare() {
super.prepare()
autoresizingMask = .flexibleWidth
interimSpacePreset = .interimSpace4
contentEdgeInsetsPreset = .wideRectangle2
interimSpacePreset = .interimSpace3
contentEdgeInsetsPreset = .square1
prepareContentView()
}
......
......@@ -189,7 +189,6 @@ open class Button: UIButton {
layoutShape()
layoutVisualLayer()
}
open override func layoutSubviews() {
super.layoutSubviews()
layoutShadowPath()
......@@ -254,7 +253,7 @@ open class Button: UIButton {
open func prepare() {
contentScaleFactor = Device.scale
contentEdgeInsetsPreset = .none
prepareVisualLayer()
prepareVisualLayer()
}
/// Prepares the visualLayer property.
......
......@@ -166,7 +166,6 @@ open class Card: PulseView {
self.init(frame: .zero)
prepareProperties(toolbar: toolbar, contentView: contentView, bottomBar: bottomBar)
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
......
......@@ -99,11 +99,7 @@ open class MenuController: RootController {
}
}
/**
To execute in the order of the layout chain, override this
method. LayoutSubviews should be called immediately, unless you
have a certain need.
*/
open override func layoutSubviews() {
super.layoutSubviews()
rootViewController.view.frame = view.bounds
......
......@@ -208,10 +208,14 @@ open class NavigationBar: UINavigationBar {
item.titleView!.grid.axis.columns = columns
for v in item.leftViews {
(v as? UIButton)?.contentEdgeInsets = .zero
if let b = v as? UIButton {
b.contentEdgeInsets = .zero
b.titleEdgeInsets = .zero
}
v.width = v.intrinsicContentSize.width
v.sizeToFit()
v.grid.columns = Int(ceil(v.width / gridFactor)) + 1
v.grid.columns = Int(ceil(v.width / gridFactor)) + 2
lc += v.grid.columns
......@@ -221,10 +225,14 @@ open class NavigationBar: UINavigationBar {
item.titleView!.grid.views.append(item.contentView)
for v in item.rightViews {
(v as? UIButton)?.contentEdgeInsets = .zero
if let b = v as? UIButton {
b.contentEdgeInsets = .zero
b.titleEdgeInsets = .zero
}
v.width = v.intrinsicContentSize.width
v.sizeToFit()
v.grid.columns = Int(ceil(v.width / gridFactor)) + 1
v.grid.columns = Int(ceil(v.width / gridFactor)) + 2
rc += v.grid.columns
......@@ -296,8 +304,8 @@ open class NavigationBar: UINavigationBar {
barStyle = .black
isTranslucent = false
depthPreset = .depth1
interimSpacePreset = .interimSpace4
contentEdgeInsetsPreset = .wideRectangle2
interimSpacePreset = .interimSpace3
contentEdgeInsetsPreset = .square1
contentScaleFactor = Device.scale
backButtonImage = Icon.cm.arrowBack
let image = UIImage.imageWithColor(color: Color.clear, size: CGSize(width: 1, height: 1))
......
......@@ -143,11 +143,6 @@ open class PageTabBarController: RootController {
prepare()
}
/**
To execute in the order of the layout chain, override this
method. LayoutSubviews should be called immediately, unless you
have a certain need.
*/
open override func layoutSubviews() {
super.layoutSubviews()
......
......@@ -52,11 +52,7 @@ open class SearchBarController: RootController {
/// Reference to the SearchBar.
open private(set) lazy var searchBar: SearchBar = SearchBar()
/**
To execute in the order of the layout chain, override this
method. LayoutSubviews should be called immediately, unless you
have a certain need.
*/
open override func layoutSubviews() {
super.layoutSubviews()
......
......@@ -76,14 +76,18 @@ open class Snackbar: Bar {
return super.hitTest(point, with: event)
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
return
}
textLabel.frame = contentView.bounds
reload()
}
/// Reloads the view.
open func reload() {
centerViews = [textLabel]
}
/**
......@@ -111,6 +115,5 @@ open class Snackbar: Bar {
textLabel.textAlignment = .left
textLabel.textColor = Color.white
textLabel.numberOfLines = 0
contentView.addSubview(textLabel)
}
}
......@@ -146,17 +146,22 @@ open class SnackbarController: RootController {
}
}
/**
To execute in the order of the layout chain, override this
method. LayoutSubviews should be called immediately, unless you
have a certain need.
*/
open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
reload()
}
open override func layoutSubviews() {
super.layoutSubviews()
guard !isAnimating else {
return
}
reload()
}
/// Reloads the view.
open func reload() {
snackbar.width = view.width
snackbar.height = snackbar.intrinsicContentSize.height + snackbar.grid.layoutEdgeInsets.top + snackbar.grid.layoutEdgeInsets.bottom
layoutSnackbar(status: snackbar.status)
......
......@@ -61,7 +61,12 @@ public protocol SwitchDelegate {
@objc(Switch)
open class Switch: UIControl {
/// An internal reference to the switchState public property.
/// Will render the view.
open var willLayout: Bool {
return 0 < width && 0 < height && nil != superview
}
/// An internal reference to the switchState public property.
private var internalSwitchState = SwitchState.off
/// Track thickness.
......@@ -297,6 +302,10 @@ open class Switch: UIControl {
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
return
}
reload()
}
......@@ -421,7 +430,7 @@ open class Switch: UIControl {
prepareSwitchSize()
}
/// Laout the button and track views.
/// Reloads the view.
open func reload() {
var w: CGFloat = intrinsicContentSize.width
let px: CGFloat = (width - w) / 2
......
......@@ -126,7 +126,6 @@ open class TabBar: Bar {
line.height = value
}
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
......
......@@ -100,13 +100,17 @@ open class Toolbar: Bar {
}
contentViewAlignment = .center == titleLabel.textAlignment ? .center : .any
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
return
}
reload()
}
/// Reloads the view.
open func reload() {
if nil != title && "" != title {
if nil == titleLabel.superview {
contentView.addSubview(titleLabel)
......
......@@ -122,8 +122,6 @@ open class ToolbarController: RootController {
view.insertSubview(v.view, aboveSubview: toolbar)
v.view.layer.zPosition = 1500
v.didMove(toParentViewController: self)
// Animate the noteButton out and the noteViewController! in.
v.view.isHidden = false
v.view.layer.rasterizationScale = Device.scale
v.view.layer.shouldRasterize = true
......@@ -134,32 +132,32 @@ open class ToolbarController: RootController {
toolbar.isUserInteractionEnabled = false
delegate?.toolbarControllerWillOpenFloatingViewController?(toolbarController: self)
UIView.animate(withDuration: 0.5,
animations: { [weak self] in
if let s = self {
v.view.center.y = s.view.bounds.height / 2
s.toolbar.alpha = 0.5
s.rootViewController.view.alpha = 0.5
}
}) { [weak self] _ in
if let s = self {
v.view.layer.shouldRasterize = false
s.view.layer.shouldRasterize = false
DispatchQueue.main.async { [weak self] in
if let s = self {
s.delegate?.toolbarControllerDidOpenFloatingViewController?(toolbarController: s)
}
}
}
animations: { [weak self, v = v] in
guard let s = self else {
return
}
v.view.center.y = s.view.bounds.height / 2
s.toolbar.alpha = 0.5
s.rootViewController.view.alpha = 0.5
}) { [weak self, v = v] _ in
guard let s = self else {
return
}
v.view.layer.shouldRasterize = false
s.view.layer.shouldRasterize = false
DispatchQueue.main.async { [weak self] in
if let s = self {
s.delegate?.toolbarControllerDidOpenFloatingViewController?(toolbarController: s)
}
}
}
}
}
}
/**
To execute in the order of the layout chain, override this
method. LayoutSubviews should be called immediately, unless you
have a certain need.
*/
open override func layoutSubviews() {
super.layoutSubviews()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment