Skip to content

Commit

Permalink
Improve FloatingButton styling by removing shadow and introducing sty…
Browse files Browse the repository at this point in the history
…ling that is similar to other UI components.
  • Loading branch information
MaximAlien committed Sep 13, 2022
1 parent b823f31 commit 1eb5f68
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 47 deletions.
3 changes: 3 additions & 0 deletions Example/ViewController.swift
Expand Up @@ -642,6 +642,7 @@ class ViewController: UIViewController {
// Hide `WayNameView` and `FloatingStackView` to smoothly present them.
navigationViewController.navigationView.wayNameView.alpha = 0.0
navigationViewController.navigationView.floatingStackView.alpha = 0.0
navigationViewController.navigationView.speedLimitView.alpha = 0.0

present(navigationViewController, animated: animated) {
completion?()
Expand All @@ -655,6 +656,7 @@ class ViewController: UIViewController {
animations: {
navigationViewController.navigationView.wayNameView.alpha = 1.0
navigationViewController.navigationView.floatingStackView.alpha = 1.0
navigationViewController.navigationView.speedLimitView.alpha = 1.0
})
navigationViewController.navigationView.topBannerContainerView.show(duration: 1.0)
}
Expand All @@ -674,6 +676,7 @@ class ViewController: UIViewController {
animations: {
activeNavigationViewController.navigationView.wayNameView.alpha = 0.0
activeNavigationViewController.navigationView.floatingStackView.alpha = 0.0
activeNavigationViewController.navigationView.speedLimitView.alpha = 0.0
},
completion: { _ in
activeNavigationViewController.dismiss(animated: animated) {
Expand Down
19 changes: 14 additions & 5 deletions Sources/MapboxNavigation/CameraController.swift
Expand Up @@ -105,20 +105,23 @@ class CameraController: NavigationComponent, NavigationComponentDelegate {
}

@objc func navigationCameraStateDidChange(_ notification: Notification) {
guard let navigationCameraState = notification.userInfo?[NavigationCamera.NotificationUserInfoKey.state] as? NavigationCameraState else { return }
guard let navigationViewController = navigationViewData.containerViewController as? NavigationViewController,
let navigationCameraState = notification.userInfo?[NavigationCamera.NotificationUserInfoKey.state] as? NavigationCameraState else {
return
}

updateNavigationCameraViewport()

switch navigationCameraState {
case .transitionToFollowing, .following:
navigationViewData.navigationView.overviewButton.isHidden = false
navigationViewController.overviewButton.isHidden = false
navigationViewData.navigationView.resumeButton.isHidden = true
if let _ = navigationViewData.navigationView.wayNameView.text?.nonEmptyString {
navigationViewData.navigationView.wayNameView.containerView.isHidden = false
}
break
case .idle, .transitionToOverview, .overview:
navigationViewData.navigationView.overviewButton.isHidden = true
navigationViewController.overviewButton.isHidden = true
navigationViewData.navigationView.resumeButton.isHidden = false
navigationViewData.navigationView.wayNameView.containerView.isHidden = true
break
Expand Down Expand Up @@ -165,8 +168,14 @@ class CameraController: NavigationComponent, NavigationComponentDelegate {
// MARK: NavigationComponentDelegate Implementation

func navigationViewDidLoad(_: UIView) {
navigationViewData.navigationView.overviewButton.addTarget(self, action: #selector(overview(_:)), for: .touchUpInside)
navigationViewData.navigationView.resumeButton.addTarget(self, action: #selector(recenter(_:)), for: .touchUpInside)
let navigationViewController = navigationViewData.containerViewController as? NavigationViewController
navigationViewController?.overviewButton.addTarget(self,
action: #selector(overview(_:)),
for: .touchUpInside)

navigationViewData.navigationView.resumeButton.addTarget(self,
action: #selector(recenter(_:)),
for: .touchUpInside)

navigationMapView.userLocationStyle = .courseView()
navigationViewData.navigationView.resumeButton.isHidden = true
Expand Down
4 changes: 3 additions & 1 deletion Sources/MapboxNavigation/DayStyle.swift
Expand Up @@ -247,6 +247,8 @@ open class DayStyle: Style {

FloatingButton.appearance(for: traitCollection).backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
FloatingButton.appearance(for: traitCollection).tintColor = tintColor
FloatingButton.appearance(for: traitCollection).borderWidth = Style.defaultBorderWidth
FloatingButton.appearance(for: traitCollection).borderColor = #colorLiteral(red: 0.737254902, green: 0.7960784314, blue: 0.8705882353, alpha: 1)

DistanceRemainingLabel.appearance(for: traitCollection).normalFont = UIFont.systemFont(ofSize: 18.0, weight: .medium).adjustedFont
DistanceRemainingLabel.appearance(for: traitCollection).normalTextColor = #colorLiteral(red: 0.431372549, green: 0.431372549, blue: 0.431372549, alpha: 1)
Expand All @@ -262,7 +264,7 @@ open class DayStyle: Style {
ResumeButton.appearance(for: traitCollection).backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
ResumeButton.appearance(for: traitCollection).tintColor = .defaultPrimaryText
ResumeButton.appearance(for: traitCollection).borderColor = #colorLiteral(red: 0.737254902, green: 0.7960784314, blue: 0.8705882353, alpha: 1)
ResumeButton.appearance(for: traitCollection).borderWidth = 1 / UIScreen.main.scale
ResumeButton.appearance(for: traitCollection).borderWidth = Style.defaultBorderWidth
ResumeButton.appearance(for: traitCollection).cornerRadius = 5.0

NextBannerView.appearance(for: traitCollection).backgroundColor = #colorLiteral(red: 0.9675388083, green: 0.9675388083, blue: 0.9675388083, alpha: 1)
Expand Down
24 changes: 19 additions & 5 deletions Sources/MapboxNavigation/FloatingButton.swift
Expand Up @@ -44,16 +44,30 @@ open class FloatingButton: Button {
- parameter image: The `UIImage` of this button.
- parameter selectedImage: The `UIImage` of this button when selected.
- parameter size: The size of this button, or `FloatingButton.buttonSize` if this argument is not specified.
- parameter type: `UIButton` type. Defaults to `.custom`.
- parameter cornerRadius: Corner radius of the button.
- returns: `FloatingButton` instance.
*/
public class func rounded<T: FloatingButton>(image: UIImage? = nil,
selectedImage: UIImage? = nil,
size: CGSize = FloatingButton.buttonSize) -> T {
let button = T.init(type: .custom)
size: CGSize = FloatingButton.buttonSize,
type: UIButton.ButtonType = .custom,
cornerRadius: CGFloat = FloatingButton.buttonSize.width / 2.0) -> T {
let button = T.init(type: type)
button.translatesAutoresizingMaskIntoConstraints = false
button.constrainedSize = size
button.setImage(image, for: .normal)
if let selected = selectedImage { button.setImage(selected, for: .selected) }
button.applyDefaultCornerRadiusShadow(cornerRadius: size.width / 2)
button.layer.cornerRadius = cornerRadius
button.imageView?.contentMode = .scaleAspectFit

if let image = image {
button.setImage(image, for: .normal)
}

if let selectedImage = selectedImage {
button.setImage(selectedImage, for: .selected)
}

return button
}
}
Expand Up @@ -90,7 +90,8 @@ open class InstructionsCardViewController: UIViewController {
lazy var junctionView: JunctionView = {
let view: JunctionView = .forAutoLayout()
view.isHidden = true
view.applyDefaultCornerRadiusShadow(cornerRadius: 4, shadowOpacity: 0.4)
view.layer.cornerRadius = Style.defaultCornerRadius

return view
}()

Expand Down
14 changes: 1 addition & 13 deletions Sources/MapboxNavigation/NavigationView.swift
Expand Up @@ -44,13 +44,6 @@ open class NavigationView: UIView {
static let buttonSpacing: CGFloat = 8.0
}

private enum Images {
static let overview = UIImage(named: "overview", in: .mapboxNavigation, compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)
static let volumeUp = UIImage(named: "volume_up", in: .mapboxNavigation, compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)
static let volumeOff = UIImage(named: "volume_off", in: .mapboxNavigation, compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)
static let feedback = UIImage(named: "feedback", in: .mapboxNavigation, compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)
}

var compactConstraints = [NSLayoutConstraint]()
var regularConstraints = [NSLayoutConstraint]()

Expand Down Expand Up @@ -125,10 +118,6 @@ open class NavigationView: UIView {
return stackView
}()

lazy var overviewButton = FloatingButton.rounded(image: Images.overview)
lazy var muteButton = FloatingButton.rounded(image: Images.volumeUp, selectedImage: Images.volumeOff)
lazy var reportButton = FloatingButton.rounded(image: Images.feedback)

var floatingButtonsPosition: MapOrnamentPosition = .topTrailing {
didSet {
setupConstraints()
Expand All @@ -143,7 +132,7 @@ open class NavigationView: UIView {
}
}

lazy var resumeButton: ResumeButton = .forAutoLayout()
lazy var resumeButton: ResumeButton = .forAutoLayout(hidden: true)

var wayNameViewLayoutGuide: UILayoutGuide? {
didSet {
Expand Down Expand Up @@ -226,7 +215,6 @@ open class NavigationView: UIView {

func commonInit() {
DayStyle().apply()
floatingButtons = [overviewButton, muteButton, reportButton]
setupViews()
setupConstraints()
}
Expand Down
37 changes: 34 additions & 3 deletions Sources/MapboxNavigation/NavigationViewController.swift
Expand Up @@ -235,6 +235,28 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
navigationService.router
}

lazy var overviewButton: FloatingButton = {
let floatingButton = FloatingButton.rounded(image: .overview)
floatingButton.borderWidth = Style.defaultBorderWidth

return floatingButton
}()

lazy var muteButton: FloatingButton = {
let floatingButton = FloatingButton.rounded(image: .volumeUp,
selectedImage: .volumeOff)
floatingButton.borderWidth = Style.defaultBorderWidth

return floatingButton
}()

lazy var reportButton: FloatingButton = {
let floatingButton = FloatingButton.rounded(image: .feedback)
floatingButton.borderWidth = Style.defaultBorderWidth

return floatingButton
}()

func setupNavigationService() {
guard let routeResponse = _routeResponse,
let routeIndex = _routeIndex,
Expand Down Expand Up @@ -365,7 +387,16 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter

open override func loadView() {
let frame = parent?.view.bounds ?? UIScreen.main.bounds
view = NavigationView(delegate: self, frame: frame, tileStoreLocation: mapTileStore, navigationMapView: self.navigationOptions?.navigationMapView)
view = NavigationView(delegate: self,
frame: frame,
tileStoreLocation: mapTileStore,
navigationMapView: self.navigationOptions?.navigationMapView)

navigationView.floatingButtons = [
overviewButton,
muteButton,
reportButton
]
}

/**
Expand Down Expand Up @@ -503,7 +534,7 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
public var showsReportFeedback: Bool = true {
didSet {
loadViewIfNeeded()
ornamentsController?.reportButton.isHidden = !showsReportFeedback
reportButton.isHidden = !showsReportFeedback
showsEndOfRouteFeedback = showsReportFeedback
}
}
Expand Down Expand Up @@ -603,7 +634,7 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
subviewInits.removeAll()

arrivalController?.destination = route?.legs.last?.destination
ornamentsController?.reportButton.isHidden = !showsReportFeedback
reportButton.isHidden = !showsReportFeedback
}

func addTopBanner(_ navigationOptions: NavigationOptions?) -> ContainerViewController {
Expand Down
1 change: 1 addition & 0 deletions Sources/MapboxNavigation/NightStyle.swift
Expand Up @@ -26,6 +26,7 @@ open class NightStyle: DayStyle {

FloatingButton.appearance(for: traitCollection).backgroundColor = .defaultDarkAppearanceBackgroundColor
FloatingButton.appearance(for: traitCollection).tintColor = #colorLiteral(red: 0.9842069745, green: 0.9843751788, blue: 0.9841964841, alpha: 1)
FloatingButton.appearance(for: traitCollection).borderColor = #colorLiteral(red: 0.3764705882, green: 0.4901960784, blue: 0.6117647059, alpha: 0.796599912)

InstructionsCardContainerView.appearance(for: traitCollection, whenContainedInInstancesOf: [InstructionsCardCell.self]).customBackgroundColor = .defaultDarkAppearanceBackgroundColor
InstructionsCardContainerView.appearance(for: traitCollection, whenContainedInInstancesOf: [InstructionsCardCell.self]).separatorColor = #colorLiteral(red: 0.3764705882, green: 0.4901960784, blue: 0.6117647059, alpha: 0.796599912)
Expand Down
21 changes: 14 additions & 7 deletions Sources/MapboxNavigation/OrnamentsController.swift
Expand Up @@ -118,10 +118,6 @@ class OrnamentsController: NavigationComponent, NavigationComponentDelegate {
}
}

var reportButton: FloatingButton {
return navigationView.reportButton
}

@objc func toggleMute(_ sender: UIButton) {
sender.isSelected = !sender.isSelected

Expand Down Expand Up @@ -211,13 +207,24 @@ class OrnamentsController: NavigationComponent, NavigationComponentDelegate {
// MARK: NavigationComponentDelegate implementation

func navigationViewDidLoad(_: UIView) {
navigationView.muteButton.addTarget(self, action: #selector(toggleMute(_:)), for: .touchUpInside)
navigationView.reportButton.addTarget(self, action: #selector(feedback(_:)), for: .touchUpInside)
guard let navigationViewController = navigationViewData.containerViewController as? NavigationViewController else {
return
}

navigationViewController.muteButton.addTarget(self,
action: #selector(toggleMute(_:)),
for: .touchUpInside)

navigationViewController.reportButton.addTarget(self,
action: #selector(feedback(_:)),
for: .touchUpInside)
}

func navigationViewWillAppear(_: Bool) {
resumeNotifications()
navigationView.muteButton.isSelected = NavigationSettings.shared.voiceMuted

let navigationViewController = navigationViewData.containerViewController as? NavigationViewController
navigationViewController?.muteButton.isSelected = NavigationSettings.shared.voiceMuted
}

func navigationViewDidDisappear(_: Bool) {
Expand Down
3 changes: 1 addition & 2 deletions Sources/MapboxNavigation/ReportButton.swift
Expand Up @@ -6,7 +6,6 @@ import UIKit
public class ReportButton: Button {

static let defaultInsets: UIEdgeInsets = 10.0
static let defaultCornerRadius: CGFloat = 4.0

public required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
Expand All @@ -22,6 +21,6 @@ public class ReportButton: Button {

private func commonInit() {
contentEdgeInsets = ReportButton.defaultInsets
applyDefaultCornerRadiusShadow(cornerRadius: ReportButton.defaultCornerRadius)
layer.cornerRadius = Style.defaultCornerRadius
}
}
8 changes: 8 additions & 0 deletions Sources/MapboxNavigation/Style.swift
Expand Up @@ -49,6 +49,14 @@ open class Style: NSObject {
UITraitCollection(userInterfaceIdiom: .pad),
])

class var defaultBorderWidth: CGFloat {
1 / UIScreen.main.scale
}

class var defaultCornerRadius: CGFloat {
10.0
}

/**
Applies the style for all changed properties.
*/
Expand Down
16 changes: 16 additions & 0 deletions Sources/MapboxNavigation/UIImage.swift
Expand Up @@ -2,6 +2,22 @@ import UIKit

extension UIImage {

static let overview = UIImage(named: "overview",
in: .mapboxNavigation,
compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)

static let volumeUp = UIImage(named: "volume_up",
in: .mapboxNavigation,
compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)

static let volumeOff = UIImage(named: "volume_off",
in: .mapboxNavigation,
compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)

static let feedback = UIImage(named: "feedback",
in: .mapboxNavigation,
compatibleWith: nil)!.withRenderingMode(.alwaysTemplate)

convenience init?(color: UIColor, size: CGSize = CGSize(width: 1.0, height: 1.0)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
Expand Down
7 changes: 0 additions & 7 deletions Sources/MapboxNavigation/UIView.swift
Expand Up @@ -48,13 +48,6 @@ extension UIView {

// MARK: Layer Styling

func applyDefaultCornerRadiusShadow(cornerRadius: CGFloat? = 4, shadowOpacity: CGFloat? = 0.1) {
layer.cornerRadius = cornerRadius!
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowRadius = 4
layer.shadowOpacity = Float(shadowOpacity!)
}

func applyGradient(colors: [UIColor], locations: [NSNumber]? = nil) {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = self.bounds
Expand Down
Expand Up @@ -488,13 +488,13 @@ class NavigationViewControllerTests: TestCase {
3,
"There should be three floating buttons by default.")
XCTAssertEqual(navigationViewController.floatingButtons?[0],
navigationViewController.navigationView.overviewButton,
navigationViewController.overviewButton,
"Unexpected floating button.")
XCTAssertEqual(navigationViewController.floatingButtons?[1],
navigationViewController.navigationView.muteButton,
navigationViewController.muteButton,
"Unexpected floating button.")
XCTAssertEqual(navigationViewController.floatingButtons?[2],
navigationViewController.navigationView.reportButton,
navigationViewController.reportButton,
"Unexpected floating button.")

navigationViewController.floatingButtons = []
Expand Down

0 comments on commit 1eb5f68

Please sign in to comment.