{"id":1411,"url":"https://github.com/andreamazz/SubtleVolume","last_synced_at":"2025-08-02T04:31:11.616Z","repository":{"id":62456295,"uuid":"53206899","full_name":"andreamazz/SubtleVolume","owner":"andreamazz","description":"Replace the system volume popup with a more subtle indicator.","archived":false,"fork":false,"pushed_at":"2020-06-12T15:24:51.000Z","size":1185,"stargazers_count":1198,"open_issues_count":6,"forks_count":65,"subscribers_count":21,"default_branch":"master","last_synced_at":"2024-04-14T15:07:08.401Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreamazz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"andreamazz"}},"created_at":"2016-03-05T15:03:38.000Z","updated_at":"2024-04-13T02:53:34.000Z","dependencies_parsed_at":"2022-11-02T00:17:14.844Z","dependency_job_id":null,"html_url":"https://github.com/andreamazz/SubtleVolume","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreamazz%2FSubtleVolume","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreamazz%2FSubtleVolume/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreamazz%2FSubtleVolume/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreamazz%2FSubtleVolume/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreamazz","download_url":"https://codeload.github.com/andreamazz/SubtleVolume/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228438911,"owners_count":17920014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:15:45.834Z","updated_at":"2024-12-06T08:31:01.552Z","avatar_url":"https://github.com/andreamazz.png","language":"Swift","funding_links":["https://github.com/sponsors/andreamazz","https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=46FNZD4PDVNRU"],"categories":["Media","Swift"],"sub_categories":["Audio","Other free courses"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg width=\"420\" src=\"assets/logo.png\"/\u003e\n\u003c/p\u003e\n\n[![CocoaPods](https://cocoapod-badges.herokuapp.com/v/SubtleVolume/badge.svg)](http://cocoapods.org/?q=subtlevolume)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n![Swift 5.0](https://img.shields.io/badge/swift-5.0-orange.svg)\n\nReplace the volume popup with a more subtle way to display the volume when the user changes it with the volume rocker.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"640\" src=\"assets/screenshot.png\"/\u003e\n\u003c/p\u003e\n\n# Why and how\nThe iOS default popover showing the volume status that appears when the user clicks the volume rocker is a big obtrusive glossy view that covers the content shown. This library offers a way to show a more subtle indicator.\nTo make sure that the popover is not shown there are two conditions that need to be satisfied:\n- An `AVAudioSession` needs to be active\n- An `MPVolumeView` needs to be in the current view's hierarchy, and its alpha needs to be greater than 0\n\nOnce a `SubtleVolume` is added to your view, an audio session is automatically started, and the view's alpha is set to `0.0001` in the hidden state.\n\n# Getting Started\nCreate an instance of `SubtleVolume` with one of its convenience initializers, and set its position (you can either set the frame or let autolayout handle it):\n```swift\nlet volume = SubtleVolume(style: .plain)\nvolume.frame = CGRect(x: 0, y: 10, width: UIScreen.main.bounds.width, height: 4) // or wherever you like\n```\n\nSet the barTintColor property:\n```swift\nvolume.barTintColor = .red\n```\n\nSet the animation type if needed (no animation will result in the indicator being always visible):\n```swift\nvolume.animation = .slideDown\n```\n\nAdd the view to your hierarchy:\n```swift\nview.addSubview(volume)\n```\n\nTo change the volume programmatically:\n```swift\ntry? volume.setVolumeLevel(0.5)\n```\n\nOr use the convenience methods:\n```swift\ntry? volume.decreaseVolume(by: 0.2, animated: true)\ntry? volume.increaseVolume(by: 0.2, animated: true)\n```\n\n### Accessory image\nYou can provide an accessory image that will be shown to the bar's left. See the delegate method:\n```swift\nfunc subtleVolume(_ subtleVolume: SubtleVolume, accessoryFor value: Double) -\u003e UIImage? {\n  return value \u003e 0 ? #imageLiteral(resourceName: \"volume-on.pdf\") : #imageLiteral(resourceName: \"volume-off.pdf\")\n}\n```\n\n### iPhone X(S/R) support\nWant to be fancy and show the volume bar in the notch area? Check out the demo project. The main gist is this:\n\n```swift\nclass ViewController: UIViewController {\n  let volume = SubtleVolume(style: .rounded)\n  var statusBarVisible = true\n\n  // ...\n\n  override func viewDidLayoutSubviews() {\n    super.viewDidLayoutSubviews()\n\n    if view.safeAreaInsets.top \u003e 0 {\n      volume.padding = CGSize(width: 2, height: 8)\n      volume.frame = CGRect(x: 16, y: 8, width: 60, height: 20)\n    } else {\n      // older phones here\n    }\n  }\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .lightContent\n  }\n\n  override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {\n    return .slide\n  }\n\n  override var prefersStatusBarHidden: Bool {\n    return !statusBarVisible\n  }\n}\n\nextension ViewController: SubtleVolumeDelegate {\n  func subtleVolume(_ subtleVolume: SubtleVolume, didChange value: Double) {\n    if !subtleVolume.isAnimating \u0026\u0026 view.safeAreaInsets.top \u003e 0 {\n      statusBarVisible = true\n      UIView.animate(withDuration: 0.1) {\n        self.setNeedsStatusBarAppearanceUpdate()\n      }\n    }\n  }\n\n  func subtleVolume(_ subtleVolume: SubtleVolume, willChange value: Double) {\n    if !subtleVolume.isAnimating \u0026\u0026 view.safeAreaInsets.top \u003e 0 {\n      statusBarVisible = false\n      UIView.animate(withDuration: 0.1) {\n        self.setNeedsStatusBarAppearanceUpdate()\n      }\n    }\n  }\n}\n```\n\n\n# Handle the background state\n\nOnce your app goes in background, you'll need to resume the session when it becomes active:\n\n```swift\nNotificationCenter.default.addObserver(volume, selector: #selector(SubtleVolume.resume), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)\n```\n\nSubtleVolume automatically removes the observer on deinit.\n\n# Hire us\nWritten by [Andrea Mazzini](https://twitter.com/theandreamazz). We're available for freelance work, feel free to contact us [here](https://www.fancypixel.it/contact/).\n\nWant to support the development of [these free libraries](https://cocoapods.org/owners/734)? Buy me a coffee ☕️ via [Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=46FNZD4PDVNRU).\n\n# MIT License\n\n\tCopyright (c) 2017-2018 Andrea Mazzini. All rights reserved.\n\n\tPermission is hereby granted, free of charge, to any person obtaining a\n\tcopy of this software and associated documentation files (the \"Software\"),\n\tto deal in the Software without restriction, including\n\twithout limitation the rights to use, copy, modify, merge, publish,\n\tdistribute, sublicense, and/or sell copies of the Software, and to\n\tpermit persons to whom the Software is furnished to do so, subject to\n\tthe following conditions:\n\n\tThe above copyright notice and this permission notice shall be included\n\tin all copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n\tOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\tMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n\tIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n\tCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n\tTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n\tSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreamazz%2FSubtleVolume","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreamazz%2FSubtleVolume","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreamazz%2FSubtleVolume/lists"}