Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated for iOS 17, Swift 5.8, and XCode 14.3.1 #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
449 changes: 0 additions & 449 deletions DrumMachine.xcodeproj/project.pbxproj

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion DrumMachine/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import CoreData
final class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
}
5 changes: 5 additions & 0 deletions DrumMachine/Sources/Features/Drums/DrumsFooterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
// Copyright © 2018 FINN.no AS. All rights reserved.
//


//This is where the "Reset" and "Close" buttons are

import UIKit

final class DrumsFooterView: UIView {
Expand All @@ -22,6 +25,8 @@ final class DrumsFooterView: UIView {
button.setTitleColor(.cherry, for: .normal)
return button
}()



// MARK: - Init

Expand Down
6 changes: 3 additions & 3 deletions DrumMachine/Sources/Features/Drums/DrumsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ extension DrumsViewController: InstrumentSelectorViewControllerDelegate {

private extension UIViewController {
func add(childController: UIViewController) {
childController.willMove(toParentViewController: self)
addChildViewController(childController)
childController.willMove(toParent: self)
addChild(_:(childController))
view.addSubview(childController.view)
childController.didMove(toParentViewController: self)
childController.didMove(toParent: self)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,45 @@ protocol InstrumentSelectorViewControllerDelegate: AnyObject {
)
}

//A big boy UIViewController class is made called InstrumentSelectorViewController, which will allow for switching between the different Instruments views

final class InstrumentSelectorViewController: UIViewController {
weak var delegate: InstrumentSelectorViewControllerDelegate?
private var selectedInstrument: Instrument
//var selectedInstrument is declared, of type, Instrument
private var instruments: [Instrument] = [.kick, .snare, .hats, .cat]

//var instruments is declared, of type, array of Instruments
//a UILabel class ccalled titleLabel is lazily declared

private lazy var titleLabel: UILabel = {
//a temporary UILabel called label is instanced within the function, that will later be returned to the parent class titleLabel
let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 18)
//the UILabel property, .font is modified
label.font = UIFont.boldSystemFont(ofSize: 36)
//the property .translatesAutoresizingMaskIntoConstraints is disabled
label.translatesAutoresizingMaskIntoConstraints = false
//the textColor property is set to custom .milk
label.textColor = .milk
//the instance of UILabel is returned to it's parent class titleLabel
return label
}()

private lazy var segmentedControl: UISegmentedControl = {
//a lazyily declared class segmentedControl, of typ UISegmentedControl is declared
let segmentedControl = UISegmentedControl(items: self.instruments.map({ $0.rawValue }))
//the .translatesAutoresizingMaskIntoConstraints attribute is disabled
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
//the .tintColor attribute is set to .white
segmentedControl.tintColor = .white
//the initialized segmentedControl function instance is returned to the segmentedControl class
return segmentedControl
}()

// MARK: - Init

//instrument is initialized, as a type of the Instrument enum
init(instrument: Instrument) {

self.selectedInstrument = instrument
super.init(nibName: nil, bundle: nil)
}
Expand All @@ -56,7 +72,7 @@ final class InstrumentSelectorViewController: UIViewController {
setupConstraints()

titleLabel.text = "Instruments"
segmentedControl.selectedSegmentIndex = instruments.index(where: { $0 == selectedInstrument}) ?? 0
segmentedControl.selectedSegmentIndex = instruments.firstIndex(where: { $0 == selectedInstrument}) ?? 0
segmentedControl.addTarget(self, action: #selector(handleSegmentedControlChange(_:)), for: .valueChanged)
}

Expand All @@ -77,7 +93,8 @@ final class InstrumentSelectorViewController: UIViewController {
}

// MARK: - Actions

//this takes a value of type UISegmentedControl and sets selectedInstrument to the currently selected instruments[] enumeration
//then the view is changed to the selected instrument by changing the delegate of InstrumentSelectorViewController to true or something
@objc private func handleSegmentedControlChange(_ sender: UISegmentedControl) {
selectedInstrument = instruments[sender.selectedSegmentIndex]
delegate?.instrumentSelectorViewController(self, didSelectInstrument: selectedInstrument)
Expand Down
28 changes: 24 additions & 4 deletions DrumMachine/Sources/Features/Pad/DrumPadCollectionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,70 @@

import UIKit

//A DrumPadCollectionViewCell class is defined of type UICollectionViewCell
final class DrumPadCollectionViewCell: UICollectionViewCell {
//a lazy var overlayLayer is made, a subclass of CALayer
private lazy var overlayLayer: CALayer = {
//layer is used as a placeeholder within the function
let layer = CALayer()
//various aesthetic customizations are modified from the CALayer parent class
layer.backgroundColor = UIColor.init(white: 1, alpha: 0.8).cgColor
//the placeholder instance is returned back to the parent class
return layer
}()

// MARK: - Init


//a rectangle is initialized as an instance of the CGRect class
override init(frame: CGRect) {
super.init(frame: frame)
//aesthetic properties are modified
contentView.addInnerShadow(shadowColor: UIColor.red, shadowSize: 10, shadowOpacity: 0.1)
//the overlayLater CALayer is passed into the addSublayer method of CGRect
contentView.layer.addSublayer(overlayLayer)
//a function setupStyles() is ran
setupStyles()
}

//a test is run to check for succesful initialization
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Layout



//I think this is giving instructions for how the tiles should be laid out, and constrains them to be within the contentView
override func layoutSubviews() {
super.layoutSubviews()
overlayLayer.frame = contentView.bounds
overlayLayer.cornerRadius = contentView.layer.cornerRadius
}

// MARK: - Styles


//a flash effect is made
func flash(withDuration duration: TimeInterval) {
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 1
animation.toValue = 0.5
animation.duration = duration
animation.autoreverses = true
animation.repeatCount = 1
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
//// animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunction).easeInEaseOut)
// animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunction).easeInEaseOut
contentView.layer.add(animation, forKey: nil)
}


//a function is made that updates overLayer.isHidden when passed a Boolean
func updateOverlayVisibility(isVisible: Bool) {
overlayLayer.isHidden = !isVisible
}


//this sets up the stiles
private func setupStyles() {
contentView.layer.masksToBounds = true
contentView.layer.cornerRadius = 2
Expand All @@ -64,6 +83,7 @@ final class DrumPadCollectionViewCell: UICollectionViewCell {

// MARK: - Private extensions

//this extends the UIView class for aesthetic purposes
private extension UIView {
func addInnerShadow(shadowColor: UIColor, shadowSize: CGFloat, shadowOpacity: Float){
let shadowLayer = CAShapeLayer()
Expand All @@ -72,7 +92,7 @@ private extension UIView {
shadowLayer.shadowOffset = CGSize(width: 0.0, height: 0.0)
shadowLayer.shadowOpacity = shadowOpacity
shadowLayer.shadowRadius = shadowSize
shadowLayer.fillRule = kCAFillRuleEvenOdd
shadowLayer.fillRule = CAShapeLayerFillRule.evenOdd

let shadowPath = CGMutablePath()
let insetRect = bounds.insetBy(dx: -shadowSize * 2.0, dy: -shadowSize * 2.0)
Expand Down
21 changes: 19 additions & 2 deletions DrumMachine/Sources/Features/Pad/DrumPadPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,54 @@

import AVFoundation

//a class initializer for the drum pads are made
final class DrumPadPlayer {
//AVAudio Session and Bundle objects are instanced privately as let
private let audioSession: AVAudioSession
private let bundle: Bundle

// MARK: - Init


//an initializer initializes some shit
init(bundle: Bundle = .main, audioSession: AVAudioSession = .sharedInstance()) {
self.bundle = bundle
self.audioSession = audioSession
try? audioSession.setCategory(AVAudioSessionCategoryPlayback)
try? audioSession.setCategory(AVAudioSession.Category.playback)
try? audioSession.setActive(true)
}

// MARK: - Player


//a fucntion play takes the currently selected instrument as input
func play(instrument: Instrument) {
//local constant sound is assigned the function makeSound(for: instrument)
guard let sound = makeSound(for: instrument) else {
//an else statemnt exits the function if unsuccesful
return
}
//the local constant sound is sent as input into AudioServicesPlaySystemSound()
AudioServicesPlaySystemSound(sound)
}


//the makeSound(for instrument) function takes Instrument as input and returns SystemSoundID? as an optional
private func makeSound(for instrument: Instrument) -> SystemSoundID? {
//a local constant holds the raw lowercased value of the instrument input
let resource = instrument.rawValue.lowercased()

//resource is passed as the Bundle.main.url(forResource: parameter and the withExtensin: parameter is set to the string literal "wav"
guard let soundURL = Bundle.main.url(forResource: resource, withExtension: "wav") else {
//otherwise nil is returned
return nil
}

//the variable sound is initialized at 0
var sound: SystemSoundID = 0
//the function AudioServicesCreateSystemSoundID fucntion is called, and soundURL is passed as CFURL
AudioServicesCreateSystemSoundID(soundURL as CFURL, &sound)
//the sound is finally returned
return sound

}
}