From fc366be8d683cc3bcd2b1d0a3158447bb1e37d8e Mon Sep 17 00:00:00 2001 From: Westin Newell Date: Thu, 11 Apr 2019 16:25:41 -0700 Subject: [PATCH] feat: add gradient to location image in PoodleSurf iOS --- .../UIKit/UIView+CornerRadius.swift | 22 ---------- .../PoodleSurf/Generic Views/Gradient.swift | 7 +++ .../StrokedCircularImageView.swift | 44 ++++++++++++++++++- .../PoodleSurf/Report/ReportHeaderView.swift | 11 +---- .../Report/ReportViewController.swift | 4 +- 5 files changed, 53 insertions(+), 35 deletions(-) diff --git a/examples/poodle-surf/ios/PoodleSurf/Extensions/UIKit/UIView+CornerRadius.swift b/examples/poodle-surf/ios/PoodleSurf/Extensions/UIKit/UIView+CornerRadius.swift index dc28d0765..d85aae424 100644 --- a/examples/poodle-surf/ios/PoodleSurf/Extensions/UIKit/UIView+CornerRadius.swift +++ b/examples/poodle-surf/ios/PoodleSurf/Extensions/UIKit/UIView+CornerRadius.swift @@ -23,26 +23,4 @@ extension UIView { layer.cornerRadius = newValue } } - - var borderWidth: CGFloat { - get { - return layer.borderWidth - } - set { - layer.borderWidth = newValue - } - } - - var borderColor: UIColor? { - get { - guard let color = layer.borderColor else { - return nil - } - - return UIColor(cgColor: color) - } - set { - layer.borderColor = newValue?.cgColor - } - } } diff --git a/examples/poodle-surf/ios/PoodleSurf/Generic Views/Gradient.swift b/examples/poodle-surf/ios/PoodleSurf/Generic Views/Gradient.swift index 157c7df21..cc14f56de 100644 --- a/examples/poodle-surf/ios/PoodleSurf/Generic Views/Gradient.swift +++ b/examples/poodle-surf/ios/PoodleSurf/Generic Views/Gradient.swift @@ -36,4 +36,11 @@ struct Gradient { self.init(colors: colors, startPoint: startPoint, endPoint: endPoint) } + + init(color: UIColor) { + let startPoint = GradientPoint(x: 0, y: 0) + let endPoint = GradientPoint(x: 1, y: 1) + + self.init(startColor: color, endColor: color, startPoint: startPoint, endPoint: endPoint) + } } diff --git a/examples/poodle-surf/ios/PoodleSurf/Generic Views/StrokedCircularImageView.swift b/examples/poodle-surf/ios/PoodleSurf/Generic Views/StrokedCircularImageView.swift index 176209b2b..4e1ab7af2 100644 --- a/examples/poodle-surf/ios/PoodleSurf/Generic Views/StrokedCircularImageView.swift +++ b/examples/poodle-surf/ios/PoodleSurf/Generic Views/StrokedCircularImageView.swift @@ -21,10 +21,35 @@ class StrokedCirularImageView: UIView { set { imageView.image = newValue } } + var strokeGradient: Gradient? { + get { return strokeView.gradient } + set { strokeView.gradient = newValue } + } + + var strokeWidth: CGFloat { + get { return strokeMaskLayer.lineWidth } + set { + strokeMaskLayer.lineWidth = newValue + updateStrokePath(forWidth: newValue) + } + } + + func setStrokeColor(_ color: UIColor?) { + guard let color = color else { + strokeGradient = nil + return + } + + strokeGradient = Gradient(color: color) + } + override func layoutSubviews() { super.layoutSubviews() - imageView.layer.cornerRadius = frame.size.width / 2 + let cornerRadius = frame.size.width / 2 + self.cornerRadius = cornerRadius + imageView.layer.cornerRadius = cornerRadius + updateStrokePath(forWidth: strokeWidth) } private func setupLayout() { @@ -33,17 +58,34 @@ class StrokedCirularImageView: UIView { let aspectConstraint = imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor) constraints.append(aspectConstraint) + constraints += embed(strokeView, shouldActivateConstraints: false) + NSLayoutConstraint.activate(constraints) } private func configureViews() { imageView.contentMode = .scaleAspectFit imageView.clipsToBounds = true + + strokeMaskLayer.fillColor = nil + strokeMaskLayer.strokeColor = UIColor.black.cgColor + + strokeView.layer.mask = strokeMaskLayer + } + + private func updateStrokePath(forWidth width: CGFloat) { + /// Since the stroke is rendered around the line we need to inset the path by half the stroke width. + let insetAmount = width / 2 + let strokeBounds = strokeView.frame.insetBy(dx: insetAmount, dy: insetAmount) + let cornerRadius = strokeView.frame.size.width / 2 + strokeMaskLayer.path = UIBezierPath(roundedRect: strokeBounds, cornerRadius: cornerRadius).cgPath } override class var requiresConstraintBasedLayout: Bool { return true } private let imageView = UIImageView() + private let strokeView = GradientView() + private let strokeMaskLayer = CAShapeLayer() @available(*, unavailable) required init?(coder aDecoder: NSCoder) { fatalError("\(#function) not implemented.") } diff --git a/examples/poodle-surf/ios/PoodleSurf/Report/ReportHeaderView.swift b/examples/poodle-surf/ios/PoodleSurf/Report/ReportHeaderView.swift index 92188544c..dbcd7d4b0 100644 --- a/examples/poodle-surf/ios/PoodleSurf/Report/ReportHeaderView.swift +++ b/examples/poodle-surf/ios/PoodleSurf/Report/ReportHeaderView.swift @@ -49,10 +49,7 @@ class ReportHeaderView: UIView { var locationImageWidthAndHeight: CGFloat { get { return locationImageWidthConstraint.constant } - set { - locationImageWidthConstraint.constant = newValue - updateLocationImageCornerRadius(forImageWidthAndHeight: newValue) - } + set { locationImageWidthConstraint.constant = newValue } } var labelsVerticalSpacing: CGFloat { @@ -116,12 +113,6 @@ class ReportHeaderView: UIView { bannerImageView.contentMode = .scaleAspectFill bannerImageView.clipsToBounds = true - - updateLocationImageCornerRadius(forImageWidthAndHeight: locationImageWidthAndHeight) - } - - private func updateLocationImageCornerRadius(forImageWidthAndHeight value: CGFloat) { - locationImageView.layer.cornerRadius = value / 2 } @available(*, unavailable) diff --git a/examples/poodle-surf/ios/PoodleSurf/Report/ReportViewController.swift b/examples/poodle-surf/ios/PoodleSurf/Report/ReportViewController.swift index dee86177f..a90fe8281 100644 --- a/examples/poodle-surf/ios/PoodleSurf/Report/ReportViewController.swift +++ b/examples/poodle-surf/ios/PoodleSurf/Report/ReportViewController.swift @@ -45,8 +45,8 @@ class ReportViewController: UIViewController { view.regionLabel.font = UIFont.systemFont(ofSize: 20, weight: .bold) view.placeLabel.font = UIFont.systemFont(ofSize: 12) view.pinIconImageView.image = UIImage(named: "Map Pin") - view.locationImageView.borderColor = UIColor(red: 0.98, green: 0.35, blue: 0.4, alpha: 1) - view.locationImageView.borderWidth = 3 + view.locationImageView.strokeGradient = Gradient.makeExample() + view.locationImageView.strokeWidth = 3 view.locationImageWidthAndHeight = 106 view.bannerHeight = 149 view.labelsStackViewLayoutMargins = UIEdgeInsets(top: 15, left: 20, bottom: 15, right: 20)