diff --git a/ACKategories-iOS/GradientView.swift b/ACKategories-iOS/GradientView.swift index 684a1765..d6e5fcb6 100644 --- a/ACKategories-iOS/GradientView.swift +++ b/ACKategories-iOS/GradientView.swift @@ -19,7 +19,21 @@ open class GradientView: UIView { // MARK: - Private properties - private var colors: [UIColor] + /// The axis of the gradient: `.vertical` for bottom-to-top gradient, `.horizontal` for left-to-right gradient. + /// + /// Default value is `.vertical` + public var axis: NSLayoutConstraint.Axis { + didSet { + setupAxis() + } + } + + /// The colors to be used for the gradient + public var colors: [UIColor] { + didSet { + setupGradientColors() + } + } // MARK: - Initializers @@ -29,24 +43,18 @@ open class GradientView: UIView { - colors: The colors to be used for the gradient. - axis: The axis of the gradient: `.vertical` for bottom-to-top gradient, `.horizontal` for left-to-right gradient. */ - public init(colors: [UIColor], axis: NSLayoutConstraint.Axis) { + public init(colors: [UIColor] = [], axis: NSLayoutConstraint.Axis = .vertical) { + self.axis = axis self.colors = colors super.init(frame: CGRect(x: 0, y: 0, width: 1, height: 1)) guard let gradientLayer = layer as? CAGradientLayer else { return } + gradientLayer.frame = bounds isUserInteractionEnabled = false - gradientLayer.frame = bounds + setupAxis() setupGradientColors() - - if axis == .vertical { - gradientLayer.startPoint = CGPoint(x: 0.5, y: 0) - gradientLayer.endPoint = CGPoint(x: 0.5, y: 1) - } else { - gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) - gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) - } } required public init?(coder aDecoder: NSCoder) { @@ -67,4 +75,15 @@ open class GradientView: UIView { guard let gradientLayer = layer as? CAGradientLayer else { return } gradientLayer.colors = colors.map { $0.cgColor } } + + private func setupAxis() { + guard let gradientLayer = layer as? CAGradientLayer else { return } + if axis == .vertical { + gradientLayer.startPoint = CGPoint(x: 0.5, y: 0) + gradientLayer.endPoint = CGPoint(x: 0.5, y: 1) + } else { + gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) + gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) + } + } } diff --git a/ACKategories.xcodeproj/project.pbxproj b/ACKategories.xcodeproj/project.pbxproj index cf2ed920..3d792631 100644 --- a/ACKategories.xcodeproj/project.pbxproj +++ b/ACKategories.xcodeproj/project.pbxproj @@ -108,6 +108,7 @@ 69FA5FBD23C868A900B44BCD /* ModalFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FA5FAC23C868A900B44BCD /* ModalFlowCoordinator.swift */; }; 69FA5FC223C8690A00B44BCD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 69FA5FC123C8690A00B44BCD /* LaunchScreen.storyboard */; }; 6A31C9F3250572FE0047A983 /* SelfSizingTableHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A31C9F2250572FE0047A983 /* SelfSizingTableHeaderFooterView.swift */; }; + 88EDD90425B8252E00207987 /* GradientViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EDD90325B8252E00207987 /* GradientViewController.swift */; }; A33559012555270F009B9D89 /* FlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33559002555270F009B9D89 /* FlowCoordinatorTests.swift */; }; A38883E3257E2D2D00B958DD /* ErrorHandlers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A38883E2257E2D2D00B958DD /* ErrorHandlers.swift */; }; A3BA685B256BEC7B006DB42F /* UIWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BA685A256BEC7B006DB42F /* UIWindow.swift */; }; @@ -269,6 +270,7 @@ 69FA5FC323C869A200B44BCD /* ACKategories.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = ACKategories.podspec; sourceTree = ""; }; 69FA5FE423C8712D00B44BCD /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 6A31C9F2250572FE0047A983 /* SelfSizingTableHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfSizingTableHeaderFooterView.swift; sourceTree = ""; }; + 88EDD90325B8252E00207987 /* GradientViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientViewController.swift; sourceTree = ""; }; A33559002555270F009B9D89 /* FlowCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowCoordinatorTests.swift; sourceTree = ""; }; A38883E2257E2D2D00B958DD /* ErrorHandlers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandlers.swift; sourceTree = ""; }; A3BA685A256BEC7B006DB42F /* UIWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIWindow.swift; sourceTree = ""; }; @@ -494,6 +496,7 @@ 69FA5F9123C868A900B44BCD /* Screens */ = { isa = PBXGroup; children = ( + 88EDD8FD25B824C200207987 /* GradientView */, 69FA5F9223C868A900B44BCD /* UIControl blocks */, 69FA5F9423C868A900B44BCD /* VC composition */, 69FA5F9723C868A900B44BCD /* MapView */, @@ -580,6 +583,14 @@ path = "Flow coordinators"; sourceTree = ""; }; + 88EDD8FD25B824C200207987 /* GradientView */ = { + isa = PBXGroup; + children = ( + 88EDD90325B8252E00207987 /* GradientViewController.swift */, + ); + path = GradientView; + sourceTree = ""; + }; A3BA6858256BEC56006DB42F /* FlowCoordinator */ = { isa = PBXGroup; children = ( @@ -919,6 +930,7 @@ files = ( 69FA5FBD23C868A900B44BCD /* ModalFlowCoordinator.swift in Sources */, 69FA5FB523C868A900B44BCD /* ModalViewController.swift in Sources */, + 88EDD90425B8252E00207987 /* GradientViewController.swift in Sources */, 69FA5FBC23C868A900B44BCD /* AppFlowCoordinator.swift in Sources */, 69FA5FB023C868A900B44BCD /* VCCompositionViewController.swift in Sources */, 69FA5FB223C868A900B44BCD /* MapViewModel.swift in Sources */, diff --git a/ACKategoriesExample/Flow coordinators/AppFlowCoordinator.swift b/ACKategoriesExample/Flow coordinators/AppFlowCoordinator.swift index a610072e..b1f4dc4a 100644 --- a/ACKategoriesExample/Flow coordinators/AppFlowCoordinator.swift +++ b/ACKategoriesExample/Flow coordinators/AppFlowCoordinator.swift @@ -44,6 +44,10 @@ extension AppFlowCoordinator: ExampleListFlowDelegate { let mapVC = MapViewController(viewModel: MapViewModel()) mapVC.title = item.title navigationController?.pushViewController(mapVC, animated: true) + case .gradientView: + let gradientVC = GradientViewController() + gradientVC.title = item.title + navigationController?.pushViewController(gradientVC, animated: true) } } } diff --git a/ACKategoriesExample/Model/ExampleItem.swift b/ACKategoriesExample/Model/ExampleItem.swift index c03d8bfd..25d53d17 100644 --- a/ACKategoriesExample/Model/ExampleItem.swift +++ b/ACKategoriesExample/Model/ExampleItem.swift @@ -13,6 +13,7 @@ enum ExampleItem: CaseIterable { case viewControllerComposition case mapViewController case present + case gradientView var title: String { return data.title } var subtitle: String { return data.subtitle } @@ -23,6 +24,7 @@ enum ExampleItem: CaseIterable { case .viewControllerComposition: return ("View controller composition", "Simply embed view controller into another one") case .mapViewController: return ("Map View Controller", "Operations on MKMapView") case .present: return ("Present", "Example usage of starting flow coordinator with modal present") + case .gradientView: return ("GradientView", "Example usage of gradient view") } } } diff --git a/ACKategoriesExample/Screens/GradientView/GradientViewController.swift b/ACKategoriesExample/Screens/GradientView/GradientViewController.swift new file mode 100644 index 00000000..beedacf7 --- /dev/null +++ b/ACKategoriesExample/Screens/GradientView/GradientViewController.swift @@ -0,0 +1,64 @@ +// +// GradientViewController.swift +// ACKategoriesExample +// +// Created by Jan Mísař on 20.01.2021. +// + +import UIKit +import ACKategories + +class GradientViewController: UIViewController { + + private weak var gradientView: GradientView! + private weak var button: UIButton! + + override func loadView() { + super.loadView() + + view.backgroundColor = .white + + let gradientView = GradientView() + view.addSubview(gradientView) + gradientView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + gradientView.topAnchor.constraint(equalTo: view.topAnchor), + gradientView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + gradientView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + gradientView.trailingAnchor.constraint(equalTo: view.trailingAnchor) + ]) + self.gradientView = gradientView + + let button = UIButton(type: .system) + button.setTitle("Change colors and switch axis", for: .normal) + button.backgroundColor = .white + button.titleEdgeInsets = UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10) + view.addSubview(button) + button.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + button.centerXAnchor.constraint(equalTo: view.centerXAnchor), + button.centerYAnchor.constraint(equalTo: view.centerYAnchor) + ]) + self.button = button + } + + override func viewDidLoad() { + super.viewDidLoad() + + button.on(.touchUpInside) { [unowned self] _ in + self.gradientView.colors = GradientViewController.randomColors() + self.gradientView.axis = (self.gradientView.axis == .vertical) ? .horizontal : .vertical + } + } + + private static func randomColors() -> [UIColor] { + let colorsCount = Int.random(in: 2..<5) + + var colors = [UIColor]() + (0..