Commit 6a391ad4 by Dmitriy Stepanets

AIQ

parent c8692e26
......@@ -39,6 +39,9 @@
CD86246C25E6826A0097F3FB /* InnerShadowLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */; };
CD9B6B1125DBC723001D9B80 /* CubicCurveAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9B6B1025DBC723001D9B80 /* CubicCurveAlgorithm.swift */; };
CD9B6B1425DBCDE2001D9B80 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9B6B1325DBCDE2001D9B80 /* GraphView.swift */; };
CDC6124F25E7964700188DA7 /* CityDayTimesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6124E25E7964700188DA7 /* CityDayTimesCell.swift */; };
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6125225E79C8F00188DA7 /* DayTimeView.swift */; };
CDC6125725E7AB1A00188DA7 /* CityAirQualityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6125625E7AB1A00188DA7 /* CityAirQualityCell.swift */; };
CDD0F1E52572425200CF5017 /* SF-Pro.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CDD0F1E42572425200CF5017 /* SF-Pro.ttf */; };
CDD0F1E82572429E00CF5017 /* AppFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD0F1E72572429E00CF5017 /* AppFont.swift */; };
CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */; };
......@@ -88,6 +91,9 @@
CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InnerShadowLayer.swift; sourceTree = "<group>"; };
CD9B6B1025DBC723001D9B80 /* CubicCurveAlgorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CubicCurveAlgorithm.swift; sourceTree = "<group>"; };
CD9B6B1325DBCDE2001D9B80 /* GraphView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
CDC6124E25E7964700188DA7 /* CityDayTimesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityDayTimesCell.swift; sourceTree = "<group>"; };
CDC6125225E79C8F00188DA7 /* DayTimeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimeView.swift; sourceTree = "<group>"; };
CDC6125625E7AB1A00188DA7 /* CityAirQualityCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityAirQualityCell.swift; sourceTree = "<group>"; };
CDD0F1E42572425200CF5017 /* SF-Pro.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro.ttf"; sourceTree = "<group>"; };
CDD0F1E72572429E00CF5017 /* AppFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppFont.swift; sourceTree = "<group>"; };
CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
......@@ -232,6 +238,8 @@
CDEE8AD425DA87DD00C289DE /* CityForecastTimePeriod */,
CD86246325E66E6B0097F3FB /* CityPrecipCell */,
CD86245B25E646000097F3FB /* CitySunCell */,
CDC6124D25E7960D00188DA7 /* CityDayTimesCell */,
CDC6125525E7AAF600188DA7 /* CityAirQualityCell */,
CD822FF425D6817000A05501 /* CityForecastCell.swift */,
CD822FFD25D6976F00A05501 /* TodayAdCell.swift */,
);
......@@ -266,6 +274,23 @@
path = CityPrecipCell;
sourceTree = "<group>";
};
CDC6124D25E7960D00188DA7 /* CityDayTimesCell */ = {
isa = PBXGroup;
children = (
CDC6124E25E7964700188DA7 /* CityDayTimesCell.swift */,
CDC6125225E79C8F00188DA7 /* DayTimeView.swift */,
);
path = CityDayTimesCell;
sourceTree = "<group>";
};
CDC6125525E7AAF600188DA7 /* CityAirQualityCell */ = {
isa = PBXGroup;
children = (
CDC6125625E7AB1A00188DA7 /* CityAirQualityCell.swift */,
);
path = CityAirQualityCell;
sourceTree = "<group>";
};
CDD0F1DC2572400200CF5017 /* UI */ = {
isa = PBXGroup;
children = (
......@@ -458,6 +483,7 @@
files = (
CD82300325D69DE400A05501 /* CityConditionsCell.swift in Sources */,
CDD0F1E82572429E00CF5017 /* AppFont.swift in Sources */,
CDC6124F25E7964700188DA7 /* CityDayTimesCell.swift in Sources */,
CD17C5FB25D15B6B00EE884E /* AppCoordinator.swift in Sources */,
CD15DB3D25DA6C5100024727 /* ForecastTimePeriodControl.swift in Sources */,
CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */,
......@@ -472,10 +498,12 @@
CD17C60225D15C8500EE884E /* CoordinatorProtocol.swift in Sources */,
CD17C5FF25D15B7C00EE884E /* TodayCoordinator.swift in Sources */,
CD822FF525D6817000A05501 /* CityForecastCell.swift in Sources */,
CDC6125725E7AB1A00188DA7 /* CityAirQualityCell.swift in Sources */,
CD6B3036257262C2004B34B3 /* UIColor+Highlight.swift in Sources */,
CDEE8AD725DA882200C289DE /* PeriodForecastButton.swift in Sources */,
CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */,
CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */,
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */,
CD86246925E672A20097F3FB /* PrecipButton.swift in Sources */,
CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */,
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
......
......@@ -7,7 +7,7 @@
<key>1Weather.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
<integer>6</integer>
</dict>
<key>PG (Playground) 1.xcscheme</key>
<dict>
......
......@@ -45,6 +45,12 @@
//Next 24 hours
"next24.title" = "next 24 hours";
//Air quality
"air.quality.is" = "Air quality is";
"air.quality.good" = "Good";
"air.quality.moderate" = "Moderate";
"air.quality.bad" = "Bad";
//Tab bar tabs
"tabBar.today" = "today";
"tabBar.forecast" = "forecast";
......
......@@ -25,6 +25,14 @@ public struct AppFont {
return font
}
static func medium(size:CGFloat) -> UIFont {
guard let font = UIFont(name: "SFPro-Medium", size: size) else {
return UIFont.systemFont(ofSize: size, weight: .bold)
}
return font
}
static func semibold(size: CGFloat) -> UIFont {
guard let font = UIFont(name: "SFPro-Semibold", size: size) else {
return UIFont.systemFont(ofSize: size, weight: .semibold)
......
//
// CityAirQualityCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.02.2021.
//
import UIKit
class CityAirQualityCell: UITableViewCell {
static let kIdentifier = "cityAirQualityCell"
//Private
private let headingLabel = UILabel()
private let valueCircle = CAShapeLayer()
private let valueProgressGradient = CAGradientLayer()
private let airQualityValueLabel = UILabel()
private let airQualityLabel = UILabel()
private let airDescLabel = UILabel()
private let stackView = UIStackView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
prepareCell()
prepareHeading()
prepareAirLabels()
prepareValueProgress()
setAirQuality(value: 48)
}
override func layoutSubviews() {
super.layoutSubviews()
valueCircle.path = UIBezierPath(arcCenter: airQualityValueLabel.center,
radius: 36,
startAngle: 0,
endAngle: 2 * .pi,
clockwise: false).cgPath
let mask = CAShapeLayer()
mask.lineWidth = 6
mask.lineCap = .round
mask.strokeColor = UIColor.red.cgColor
mask.fillColor = UIColor.clear.cgColor
mask.path = UIBezierPath(arcCenter: airQualityValueLabel.center,
radius: 36,
startAngle: -.pi/2,
endAngle: 0,
clockwise: true).cgPath
valueProgressGradient.frame = .init(x: 0,
y: 0,
width: 100,
height: 100)
// valueProgressGradient.mask = valueProgressShape
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setAirQuality(value:CGFloat) {
airQualityValueLabel.text = "\(Int(value))"
let aqiText = "air.quality.is".localized()
let aqiConditionText = "air.quality.good".localized().uppercased()
let attrString = NSMutableAttributedString(string: "\(aqiText)\n\(aqiConditionText)",
attributes: [.font : AppFont.SFPro.regular(size: 24),
.foregroundColor :ThemeManager.currentTheme.secondaryTextColor])
attrString.addAttributes([.font : AppFont.SFPro.medium(size: 34)],
range: NSRange(location: aqiText.count + 1,
length: aqiConditionText.count))
airQualityLabel.attributedText = attrString
}
}
//MARK:- Prepare
private extension CityAirQualityCell {
func prepareCell() {
selectionStyle = .none
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
}
func prepareHeading() {
headingLabel.font = AppFont.SFPro.bold(size: 16)
headingLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
headingLabel.text = "AQI"
contentView.addSubview(headingLabel)
headingLabel.snp.makeConstraints { (make) in
make.top.equalToSuperview().inset(15)
make.left.equalToSuperview().inset(18)
}
}
func prepareAirLabels() {
airQualityValueLabel.font = AppFont.SFPro.bold(size: 18)
airQualityValueLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
contentView.addSubview(airQualityValueLabel)
airQualityLabel.numberOfLines = 0
airQualityLabel.lineBreakMode = .byWordWrapping
airQualityLabel.textAlignment = .left
contentView.addSubview(airQualityLabel)
airDescLabel.textAlignment = .left
airDescLabel.numberOfLines = 0
airDescLabel.lineBreakMode = .byWordWrapping
airDescLabel.font = AppFont.SFPro.regular(size: 16)
airDescLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
airDescLabel.text = "Slightly elevated pollution, but general public likely not affected"
contentView.addSubview(airDescLabel)
//Constraints
airQualityValueLabel.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(72)
make.top.equalTo(headingLabel.snp.bottom).offset(72)
}
airQualityLabel.snp.makeConstraints { (make) in
make.left.equalTo(airQualityValueLabel.snp.right).offset(54)
make.centerY.equalTo(airQualityValueLabel)
}
airDescLabel.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(50)
make.top.equalTo(airQualityLabel.snp.bottom).offset(9)
make.bottom.equalToSuperview().inset(30)
}
}
func prepareValueProgress() {
valueCircle.strokeColor = UIColor(hex: 0xe9ebfc).cgColor
valueCircle.fillColor = UIColor.clear.cgColor
valueCircle.lineWidth = 2
contentView.layer.addSublayer(valueCircle)
valueProgressGradient.type = .radial
valueProgressGradient.startPoint = .init(x: 0.5, y: 0.5)
valueProgressGradient.endPoint = .init(x: 0, y: 0)
valueProgressGradient.colors = [UIColor.red.cgColor, UIColor.yellow.cgColor]
contentView.layer.addSublayer(valueProgressGradient)
}
}
//
// CityDayTimesCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.02.2021.
//
import UIKit
class CityDayTimesCell: UITableViewCell {
static let kIdentifier = "cityDayTimesCell"
//Private
private let headingLabel = UILabel()
private let headingButton = ArrowButton()
private let stackView = UIStackView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
prepareCell()
prepareHeading()
prepareStackView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//Private
@objc private func handleArrowButton() {
}
}
private extension CityDayTimesCell {
func prepareCell() {
selectionStyle = .none
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
}
func prepareHeading() {
//Label
headingLabel.font = AppFont.SFPro.bold(size: 16)
headingLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
headingLabel.text = "next24.title".localized().uppercased()
contentView.addSubview(headingLabel)
headingLabel.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(18)
make.top.equalToSuperview().inset(15)
}
//Arrow button
headingButton.addTarget(self, action: #selector(handleArrowButton), for: .touchUpInside)
contentView.addSubview(headingButton)
headingButton.snp.makeConstraints { (make) in
make.width.height.equalTo(30)
make.right.equalToSuperview().inset(18)
make.centerY.equalTo(headingLabel)
}
}
func prepareStackView() {
stackView.axis = .horizontal
stackView.distribution = .fillProportionally
stackView.alignment = .center
stackView.spacing = 0
stackView.clipsToBounds = false
contentView.addSubview(stackView)
for (index, dayTime) in DayTime.allCases.enumerated() {
let view = DayTimeView(dayTime: dayTime, withSeparator: index < DayTime.allCases.count - 1)
stackView.addArrangedSubview(view)
}
stackView.snp.makeConstraints { (make) in
make.left.right.equalToSuperview()
make.top.equalTo(headingLabel.snp.bottom).offset(18)
make.bottom.equalToSuperview().inset(15)
}
}
}
//
// DayTimeView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.02.2021.
//
import UIKit
public enum DayTime: CaseIterable {
case morning
case noon
case evening
case night
var localized:String {
switch self {
case .morning:
return "dayTime.morning".localized()
case .noon:
return "dayTime.noon".localized()
case .evening:
return "dayTime.evening".localized()
case .night:
return "dayTime.night".localized()
}
}
}
class DayTimeView: UIView {
private let dayTimeLabel = UILabel()
private let forecastImageView = UIImageView()
private let tempLabel = UILabel()
private let dayTimeConditionLabel = UILabel()
init(dayTime:DayTime, withSeparator:Bool = false) {
super.init(frame: .zero)
prepareView()
if withSeparator {
prepareSeparator()
}
dayTimeLabel.text = dayTime.localized
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK:- Prepare
private extension DayTimeView {
func prepareView() {
dayTimeLabel.font = AppFont.SFPro.bold(size: 14)
dayTimeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
dayTimeLabel.text = "dayTime.morning".localized()
addSubview(dayTimeLabel)
forecastImageView.contentMode = .scaleAspectFit
forecastImageView.image = UIImage(named: "partly_cloudy")
addSubview(forecastImageView)
tempLabel.font = AppFont.SFPro.bold(size: 18)
tempLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
tempLabel.text = "85°"
addSubview(tempLabel)
dayTimeConditionLabel.font = AppFont.SFPro.regular(size: 14)
dayTimeConditionLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
dayTimeConditionLabel.text = "forecast.clear".localized()
addSubview(dayTimeConditionLabel)
//Constraints
dayTimeLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalToSuperview().inset(24)
}
forecastImageView.snp.makeConstraints { (make) in
make.width.height.equalTo(28)
make.centerX.equalToSuperview()
make.top.equalTo(dayTimeLabel.snp.bottom).offset(33)
}
tempLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalTo(forecastImageView.snp.bottom).offset(30)
}
dayTimeConditionLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalTo(tempLabel.snp.bottom).offset(14)
make.bottom.equalToSuperview().inset(24)
}
}
func prepareSeparator() {
let separatorView = UIView()
separatorView.backgroundColor = UIColor(hex: 0xc2c9d6)
separatorView.alpha = 0.5
addSubview(separatorView)
separatorView.snp.makeConstraints { (make) in
make.top.equalTo(dayTimeLabel)
make.bottom.equalTo(dayTimeConditionLabel)
make.right.equalToSuperview()
make.width.equalTo(1)
}
}
}
......@@ -18,6 +18,7 @@ class CityPrecipCell: UITableViewCell {
private let summaryContaier = UIView()
private let summaryImageView = UIImageView()
private let summaryLabel = UILabel()
private var levels:[CGFloat] = [0.12, 0.55, 0.21, 0.6, 0.12, 1, 0.3]
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
......@@ -101,10 +102,12 @@ private extension CityPrecipCell {
make.edges.height.equalToSuperview()
}
for index in 0..<12 {
let conditionButton = PrecipButton()
conditionButton.addTarget(self, action: #selector(handlePrecipButton(button:)), for: .touchUpInside)
stackView.addArrangedSubview(conditionButton)
for index in 0..<levels.count {
let precipButton = PrecipButton()
precipButton.isSelected = index == 1
precipButton.set(level: levels[index])
precipButton.addTarget(self, action: #selector(handlePrecipButton(button:)), for: .touchUpInside)
stackView.addArrangedSubview(precipButton)
}
}
......
......@@ -17,6 +17,7 @@ class PrecipButton: UIControl {
private let innerShadowLayer = InnerShadowLayer()
private let gradientLayer = CAGradientLayer()
private let capLayer = CAShapeLayer()
private var currentLevel:CGFloat = 1.0
override init(frame: CGRect) {
super.init(frame: frame)
......@@ -29,11 +30,16 @@ class PrecipButton: UIControl {
override func layoutSubviews() {
super.layoutSubviews()
let visualPrettyLevel = max(0.25, currentLevel)
let yOffset = valueLabel.frame.origin.y + valueLabel.bounds.height + 18
let levelHeight = timeLabel.frame.origin.y - 18 - yOffset
let valueOffset = levelHeight - levelHeight * visualPrettyLevel
//Main level
levelLayer.frame = .init(x: (self.bounds.width - kLevelWidth) / 2,
y: yOffset,
y: yOffset + valueOffset,
width: kLevelWidth,
height: timeLabel.frame.origin.y - 18 - yOffset)
height: levelHeight * visualPrettyLevel)
//Inner shadow
innerShadowLayer.frame = .init(x: 0, y: 0, width: self.levelLayer.frame.width, height: self.levelLayer.frame.height)
......@@ -51,6 +57,37 @@ class PrecipButton: UIControl {
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var isSelected: Bool {
didSet {
if isSelected {
self.backgroundColor = UIColor.white
self.valueLabel.font = AppFont.SFPro.bold(size: 16)
self.timeLabel.font = AppFont.SFPro.bold(size: 12)
self.layer.shadowColor = UIColor(hex: 0xe5e6f4).cgColor
self.layer.shadowOffset = .init(width: 5, height: 5)
self.layer.shadowRadius = 18
self.layer.shadowOpacity = 0.64
}
else {
self.backgroundColor = UIColor.white.withAlphaComponent(0.5)
self.valueLabel.font = AppFont.SFPro.regular(size: 16)
self.timeLabel.font = AppFont.SFPro.regular(size: 12)
self.layer.shadowColor = UIColor.clear.cgColor
self.layer.shadowOffset = .zero
self.layer.shadowRadius = 0
self.layer.shadowOpacity = 0
}
}
}
//Public
public func set(level:CGFloat) {
self.currentLevel = max(0, level)
self.currentLevel = min(1, level)
self.valueLabel.text = "\(Int(self.currentLevel * 100))%"
layoutSubviews()
}
}
//MARK:- Prepare
......
......@@ -13,13 +13,15 @@ private enum TodayTableCell {
case conditions
case forecastPeriod
case precipitation
case dayTime
case aqi
case sun
}
class TodayViewController: UIViewController {
//Private
private let tableView = UITableView()
private let tableCells:[TodayTableCell] = [.forecast, .ad, .conditions, .forecastPeriod, .precipitation, .sun]
private let tableCells:[TodayTableCell] = [.forecast, .ad, .conditions, .forecastPeriod, .precipitation, .dayTime, .aqi, .sun]
private var localizationObserver:Any?
deinit {
......@@ -89,6 +91,8 @@ private extension TodayViewController {
tableView.register(CityConditionsCell.self, forCellReuseIdentifier: CityConditionsCell.kIdentifier)
tableView.register(CityForecastTimePeriodCell.self, forCellReuseIdentifier: CityForecastTimePeriodCell.kIdentifier)
tableView.register(CityPrecipCell.self, forCellReuseIdentifier: CityPrecipCell.kIdentifier)
tableView.register(CityDayTimesCell.self, forCellReuseIdentifier: CityDayTimesCell.kIdentifier)
tableView.register(CityAirQualityCell.self, forCellReuseIdentifier: CityAirQualityCell.kIdentifier)
tableView.register(CitySunCell.self, forCellReuseIdentifier: CitySunCell.kIdentifier)
tableView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
tableView.separatorStyle = .none
......@@ -128,6 +132,12 @@ extension TodayViewController: UITableViewDataSource {
case .precipitation:
let cell = tableView.dequeueReusableCell(withIdentifier: CityPrecipCell.kIdentifier, for: indexPath) as! CityPrecipCell
return cell
case .dayTime:
let cell = tableView.dequeueReusableCell(withIdentifier: CityDayTimesCell.kIdentifier, for: indexPath) as! CityDayTimesCell
return cell
case .aqi:
let cell = tableView.dequeueReusableCell(withIdentifier: CityAirQualityCell.kIdentifier, for: indexPath) as! CityAirQualityCell
return cell
case .sun:
let cell = tableView.dequeueReusableCell(withIdentifier: CitySunCell.kIdentifier, for: indexPath) as! CitySunCell
return cell
......
......@@ -9,4 +9,5 @@ target '1Weather' do
pod 'SnapKit'
pod 'BezierKit'
pod 'Localize-Swift'
pod 'Cirque'
end
PODS:
- BezierKit (0.10.0)
- Cirque (1.0.3)
- Localize-Swift (3.2.0):
- Localize-Swift/LocalizeSwiftCore (= 3.2.0)
- Localize-Swift/UIKit (= 3.2.0)
......@@ -10,20 +11,23 @@ PODS:
DEPENDENCIES:
- BezierKit
- Cirque
- Localize-Swift
- SnapKit
SPEC REPOS:
trunk:
- BezierKit
- Cirque
- Localize-Swift
- SnapKit
SPEC CHECKSUMS:
BezierKit: 1828aca1675d68f0659c5353bc5b0d3399a3910c
Cirque: 1eb134f2180b33107106dc72e47340aefb054da3
Localize-Swift: 6f4475136bdb0d7b2882ea3d4ea919d70142b232
SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
PODFILE CHECKSUM: 06893793de13524c28b9afdc6dca649b77af3601
PODFILE CHECKSUM: 691dd13e39416c55752f83cfac7ea3a42e4f8f66
COCOAPODS: 1.10.1
//
// CircularMultiColorGradientView.swift
// Tonsser
//
// Created by Philip Engberg on 03/02/2017.
// Copyright © 2017 tonsser. All rights reserved.
//
import Foundation
public protocol CirqueDataType {
var color : UIColor { get }
var value : Double { get }
}
public class CirqueView : UIView {
public var dataPoints: [CirqueDataType]? {
didSet {
setNeedsDisplay()
}
}
public var transitionSize: CGFloat = 0.05
public var stepSize: CGFloat = 0.1
public var lineWidth: CGFloat = 5
fileprivate var circleRadius : CGFloat {
return (self.bounds.size.width - lineWidth)/2
}
fileprivate var circleCenter : CGPoint {
return CGPoint(x: self.bounds.size.width/2, y: self.bounds.size.height/2)
}
fileprivate func drawGradient(_ fromColor: UIColor, toColor: UIColor, from startPosition: CGFloat, with relativeSize: CGFloat) {
let zeroAngle = CGFloat(-90.0).degreesToRadians
let startAngle = zeroAngle + (CGFloat(360).degreesToRadians * startPosition)
let finalEndAngle = zeroAngle + (CGFloat(360).degreesToRadians * (startPosition + max(relativeSize, 0)))
let totalGradientSize = abs(finalEndAngle - startAngle)
var runningStartAngle = startAngle
let startColorComponents = fromColor.components
let finalColorComponents = toColor.components
let processPath = UIBezierPath()
processPath.lineWidth = lineWidth
for stepFraction in stride(from: CGFloat(0), through: 1.0, by: stepSize) {
let endAngle = (stepFraction * totalGradientSize) + startAngle
let newRed = startColorComponents.red + (finalColorComponents.red - startColorComponents.red) * stepFraction
let newGreen = startColorComponents.green + (finalColorComponents.green - startColorComponents.green) * stepFraction
let newBlue = startColorComponents.blue + (finalColorComponents.blue - startColorComponents.blue) * stepFraction
let newAlpha = startColorComponents.alpha + (finalColorComponents.alpha - startColorComponents.alpha) * stepFraction
let progressColor = UIColor(red:newRed, green:newGreen, blue:newBlue, alpha:newAlpha)
progressColor.set()
processPath.addArc(withCenter: circleCenter, radius: circleRadius, startAngle: runningStartAngle, endAngle: endAngle, clockwise: true)
processPath.stroke()
processPath.removeAllPoints()
runningStartAngle = endAngle - stepSize / 100
}
}
fileprivate func drawSolid(_ color: UIColor, from startPosition: CGFloat, with relativeSize: CGFloat) {
let zeroAngle = CGFloat(-90.0).degreesToRadians
let startAngle = zeroAngle + (CGFloat(360).degreesToRadians * startPosition)
let finalEndAngle = zeroAngle + (CGFloat(360).degreesToRadians * (startPosition + max(relativeSize, 0)))
let processPath = UIBezierPath()
processPath.lineWidth = lineWidth
color.set()
processPath.addArc(withCenter: circleCenter, radius: circleRadius, startAngle: startAngle, endAngle: finalEndAngle, clockwise: true)
processPath.stroke()
processPath.removeAllPoints()
}
override public func draw(_ rect: CGRect) {
guard let dataPoints = self.dataPoints else { return }
guard dataPoints.count > 0 else { return }
let context = UIGraphicsGetCurrentContext()
// Cleaer any previous drawings
context?.clear(rect)
var start: CGFloat = 0.0 // Start of the the stroke in radians
var size: CGFloat = 0.0 // Size (or length) of the stroke in percent
let overlapSize: CGFloat = 0.001 // How much to backtrack before drawing to ensure that there are no gaps between stroke elements
// If there is jus one data point, just draw simple solig stroke
guard dataPoints.count > 1 else {
drawSolid(dataPoints[0].color, from: start, with: CGFloat(dataPoints[0].value))
return
}
// We now have at least two data points to show and thus have to use gradients
for (index, rating) in dataPoints.enumerated() {
var cutOff: CGFloat = 0
if index == 0 || index == dataPoints.count - 1 {
cutOff = transitionSize / 2
} else {
cutOff = transitionSize
}
// Offset start point by the curresnt size
start += max(size - overlapSize, 0)
// Subtract transition cut off from intended size
size = max(CGFloat(rating.value) - cutOff, 0)
// Draw the solid part of the stroke
drawSolid(rating.color, from: start, with: size)
// If we are not at the end, we should draw a gradient
if index < dataPoints.count - 1 && dataPoints[index].value > 0 && dataPoints[index + 1].value > 0 {
start += size
size = transitionSize
let nextRating = dataPoints[index + 1]
drawGradient(rating.color, toColor: nextRating.color, from: start, with: size)
}
}
}
public func minSize(for ratings: [CirqueDataType]) -> Double {
guard ratings.count > 1 else { return 0 }
return (Double(ratings.count) - 1) * Double(transitionSize)
}
}
//
// FloatingPoint+Utility.swift
// Pods
//
// Created by Philip Engberg on 05/02/2017.
//
//
import Foundation
public extension FloatingPoint {
var degreesToRadians: Self { return self * .pi / 180 }
var radiansToDegrees: Self { return self * 180 / .pi }
}
//
// UIColor+Utility.swift
// Pods
//
// Created by Philip Engberg on 05/02/2017.
//
//
import Foundation
struct ColorComponents {
let red: CGFloat
let green: CGFloat
let blue: CGFloat
let alpha: CGFloat
}
extension UIColor {
var coreImageColor: CoreImage.CIColor {
return CoreImage.CIColor(color: self)
}
var components: ColorComponents {
let color = coreImageColor
return ColorComponents(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha)
}
}
Copyright (c) 2017 philipengberg <philipengberg@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
![cirque icon 2](/img/Cirque.png)
# Cirque
![Swift](https://img.shields.io/badge/Swift-3.0-brightgreen.svg)
[![Version](https://img.shields.io/cocoapods/v/Cirque.svg?style=flat)](http://cocoapods.org/pods/Cirque)
[![License](https://img.shields.io/cocoapods/l/Cirque.svg?style=flat)](http://cocoapods.org/pods/Cirque)
[![Platform](https://img.shields.io/cocoapods/p/Cirque.svg?style=flat)](http://cocoapods.org/pods/Cirque)
Cirque is an iOS component that enables you to draw **multi color** circle strokes with **gradient trasitions** between colors.
## Why?
`CAGradientLayer` currently only supports linear gradients, and most solutions out there only support two colors. However, we needed a modular, configurable component that could handle any number of colors at any size.
## Example
To run the example project, clone the repo, and run `pod install` from the Example directory first.
First create a data structure that implements `CirqueDataType` (an `enum` would make sense), then create a new `CirqueView` and set the `dataPoints` property with an array of `CirqueDataType`.
```swift
let cirque = CirqueView(frame: CGRect(x: 0, y: 0, width: 110, height: 110))
cirque.dataPoints = [RankingGroup.match(value: 0.3),
RankingGroup.achievements(value: 0.2),
RankingGroup.votes(value: 0.2)]
view.addSubview(cirque)
```
and boom 💥
![Example](/img/Example.png)
### Customization
You can further customize the appearance be tweaking
| Property | Description | Default value |
|:---------|:------------|:--------------|
|**`transitionSize`**| A `Float` between 0 and 1 indicating the percentage of the circle circumference that should be used to transition fully from one color to the next. | `0.05` |
|**`stepSize`**| A `Float` between 0 and 1 indicating the percentage of the `transitionSize` that each gradient step should fill. So with a value of `0.1`, each color step is 10% of the `transitionSize`, meaning there will be 10 steps in total. | `0.1` |
|**`lineWidth`**| A `Float` indicating the stroke width of the circle. | `5` |
![Expainer](/img/Explainer.png)
### How it works
The idea is to draw as much as possible with ordinary strokes on a bezier arc. Then when it's time to shift color, `1/stepSize` little arcs are drawn which each go one step closer to the next color. This is illustrated below:
![Example](/img/HowItWorks.gif)
## Animation
I have implemented a working prototype that can animate the progress of the circle, while keeping the relative proportions of the circle as it expands.
The challenge is that in order to draw many small arc segments, the most feasible thing is to do it directly in `drawRect:`, which means there are no layers to animate.
My working prototype supports custom duration and timing functions. If you would to se this supported directly in this component, please throw a 👍 on [this](https://github.com/tonsser/Cirque/issues/1) issue.
## Installation
Cirque is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod "Cirque"
```
## Requirements
* Xcode 8.0
* Swift 3.0+
## Author
**Mr. Engberg**, Lead Mobile Developer @ [Tonsser](https://github.com/tonsser)
- [![GitHub](/img/GitHub.png) philipengberg](https://github.com/philipengberg)
- [![Twitter](/img/Twitter.png) philipengberg](https://twitter.com/philipengberg)
## Contribution
Contributions are more than welcome!
## License
Cirque is available under the MIT license. See the LICENSE file for more info.
PODS:
- BezierKit (0.10.0)
- Cirque (1.0.3)
- Localize-Swift (3.2.0):
- Localize-Swift/LocalizeSwiftCore (= 3.2.0)
- Localize-Swift/UIKit (= 3.2.0)
......@@ -10,20 +11,23 @@ PODS:
DEPENDENCIES:
- BezierKit
- Cirque
- Localize-Swift
- SnapKit
SPEC REPOS:
trunk:
- BezierKit
- Cirque
- Localize-Swift
- SnapKit
SPEC CHECKSUMS:
BezierKit: 1828aca1675d68f0659c5353bc5b0d3399a3910c
Cirque: 1eb134f2180b33107106dc72e47340aefb054da3
Localize-Swift: 6f4475136bdb0d7b2882ea3d4ea919d70142b232
SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
PODFILE CHECKSUM: 06893793de13524c28b9afdc6dca649b77af3601
PODFILE CHECKSUM: 691dd13e39416c55752f83cfac7ea3a42e4f8f66
COCOAPODS: 1.10.1
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForAnalyzing = "YES"
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
buildForArchiving = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "19622742EBA51E823D6DAE3F8CDBFAD4"
......@@ -23,15 +23,14 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
......@@ -39,14 +38,17 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
buildConfiguration = "Debug"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
debugDocumentVersioning = "YES"
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
......
......@@ -9,17 +9,19 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
<key>Localize-Swift.xcscheme</key>
<key>Cirque.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>1</integer>
<integer>2</integer>
</dict>
<key>Localize-Swift.xcscheme_^#shared#^_</key>
<key>Localize-Swift.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
</dict>
......@@ -28,14 +30,14 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
<integer>4</integer>
</dict>
<key>SnapKit.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
<integer>5</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
......
<?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>en</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>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_Cirque : NSObject
@end
@implementation PodsDummy_Cirque
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double CirqueVersionNumber;
FOUNDATION_EXPORT const unsigned char CirqueVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Cirque
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Cirque
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module Cirque {
umbrella header "Cirque-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Cirque
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Cirque
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
......@@ -25,6 +25,29 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## Cirque
Copyright (c) 2017 philipengberg <philipengberg@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## Localize-Swift
Copyright (c) 2015 Roy Marmelstein (http://roysapps.com/)
......
......@@ -44,6 +44,35 @@ SOFTWARE.</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2017 philipengberg &lt;philipengberg@gmail.com&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>Cirque</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2015 Roy Marmelstein (http://roysapps.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy
......
${PODS_ROOT}/Target Support Files/Pods-1Weather/Pods-1Weather-frameworks.sh
${BUILT_PRODUCTS_DIR}/BezierKit/BezierKit.framework
${BUILT_PRODUCTS_DIR}/Cirque/Cirque.framework
${BUILT_PRODUCTS_DIR}/Localize-Swift/Localize_Swift.framework
${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework
\ No newline at end of file
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BezierKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cirque.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Localize_Swift.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework
\ No newline at end of file
${PODS_ROOT}/Target Support Files/Pods-1Weather/Pods-1Weather-frameworks.sh
${BUILT_PRODUCTS_DIR}/BezierKit/BezierKit.framework
${BUILT_PRODUCTS_DIR}/Cirque/Cirque.framework
${BUILT_PRODUCTS_DIR}/Localize-Swift/Localize_Swift.framework
${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework
\ No newline at end of file
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BezierKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cirque.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Localize_Swift.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework
\ No newline at end of file
......@@ -176,11 +176,13 @@ code_sign_if_enabled() {
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/BezierKit/BezierKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Cirque/Cirque.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Localize-Swift/Localize_Swift.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/BezierKit/BezierKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Cirque/Cirque.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Localize-Swift/Localize_Swift.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework"
fi
......
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit" "${PODS_CONFIGURATION_BUILD_DIR}/Cirque" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit/BezierKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift/Localize_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit/BezierKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cirque/Cirque.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift/Localize_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "BezierKit" -framework "CoreGraphics" -framework "Localize_Swift" -framework "SnapKit" -framework "UIKit"
OTHER_LDFLAGS = $(inherited) -framework "BezierKit" -framework "Cirque" -framework "CoreGraphics" -framework "Localize_Swift" -framework "SnapKit" -framework "UIKit"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
......
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit" "${PODS_CONFIGURATION_BUILD_DIR}/Cirque" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit/BezierKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift/Localize_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BezierKit/BezierKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cirque/Cirque.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Localize-Swift/Localize_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "BezierKit" -framework "CoreGraphics" -framework "Localize_Swift" -framework "SnapKit" -framework "UIKit"
OTHER_LDFLAGS = $(inherited) -framework "BezierKit" -framework "Cirque" -framework "CoreGraphics" -framework "Localize_Swift" -framework "SnapKit" -framework "UIKit"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
......
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