adds MOTU audio settings
TestFlight / Build and upload (push) Successful in 1m20s

This commit is contained in:
2026-07-27 20:11:52 -07:00
parent cef1770d2f
commit 50e5f80a44
6 changed files with 456 additions and 18 deletions
@@ -19,6 +19,11 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate, Serv
fileprivate var _switchesController: SwitchesViewController = SwitchesViewController()
fileprivate var _lightsController: SwitchesViewController = SwitchesViewController()
fileprivate var _audioSectionView: AudioSectionView = AudioSectionView()
fileprivate var _audioMixerController: AudioMixerViewController = AudioMixerViewController()
fileprivate var _audioMixerDimmingView: UIControl = UIControl(frame: .zero)
fileprivate var _isAudioMixerPresented: Bool = false
fileprivate var _isAudioMixerAnimating: Bool = false
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
{
@@ -56,8 +61,30 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate, Serv
_lightsController.labelText = "lights"
self.addChild(_lightsController)
self.view.addSubview(_lightsController.view)
_audioSectionView.mixerSettingsHandler = { [weak self] in
self?._presentAudioMixer()
}
self.view.addSubview(_audioSectionView)
_audioMixerController.closeHandler = { [weak self] in
self?._dismissAudioMixer()
}
self.view.addSubview(_headerView)
_audioMixerDimmingView.backgroundColor = UIColor.black
_audioMixerDimmingView.alpha = 0.0
_audioMixerDimmingView.isHidden = true
_audioMixerDimmingView.accessibilityIdentifier = "audio.dimmingView"
_audioMixerDimmingView.accessibilityLabel = "Dismiss Mixer"
_audioMixerDimmingView.accessibilityTraits = .button
_audioMixerDimmingView.addTarget(
self,
action: #selector(_audioMixerDimmingViewTapped),
for: .touchUpInside
)
self.view.addSubview(_audioMixerDimmingView)
_updateConnectivityStatus(.disconnected)
_updateSizeClassPresentation()
@@ -82,8 +109,10 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate, Serv
)
_headerView.frame = headerBounds
_audioMixerDimmingView.frame = bounds
if _visualizationShouldBeVisible() {
let sectionSpacing: CGFloat = 8.0
let visualizationFrame = CGRect(
x: bodyBounds.origin.x,
y: bodyBounds.origin.y,
@@ -103,15 +132,36 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate, Serv
dy: 0.0
)
_switchesController.view.frame = CGRect(
let rightColumnFrame = CGRect(
x: visualizationFrame.maxX,
y: bodyBounds.origin.y,
width: bodyBounds.width - visualizationFrame.width,
height: bodyBounds.height
)
let audioHeight = min(
AudioSectionView.preferredHeight(forWidth: rightColumnFrame.width),
bodyBounds.height * 0.22
)
_switchesController.view.frame = CGRect(
x: rightColumnFrame.minX,
y: rightColumnFrame.minY,
width: rightColumnFrame.width,
height: rightColumnFrame.height - audioHeight - sectionSpacing
)
_audioSectionView.frame = CGRect(
x: rightColumnFrame.minX,
y: _switchesController.view.frame.maxY + sectionSpacing,
width: rightColumnFrame.width,
height: audioHeight
)
} else {
let sectionSpacing: CGFloat = 8
let switchesHeight = rint(bodyBounds.height * 0.68)
let sectionSpacing: CGFloat = 8.0
let audioHeight = min(
AudioSectionView.preferredHeight(forWidth: bodyBounds.width),
bodyBounds.height * 0.18
)
let lightsHeight = rint(bodyBounds.height * 0.27)
let switchesHeight = bodyBounds.height - audioHeight - lightsHeight - (sectionSpacing * 2.0)
_visualizationController.view.frame = .zero
_switchesController.view.frame = CGRect(
@@ -120,14 +170,26 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate, Serv
width: bodyBounds.width,
height: switchesHeight
)
_audioSectionView.frame = CGRect(
x: bodyBounds.minX + sectionSpacing,
y: _switchesController.view.frame.maxY + sectionSpacing,
width: bodyBounds.width - (sectionSpacing * 2.0),
height: audioHeight
)
_lightsController.view.frame = CGRect(
x: bodyBounds.minX + sectionSpacing,
y: bodyBounds.minY + switchesHeight + sectionSpacing,
y: _audioSectionView.frame.maxY + sectionSpacing,
width: bodyBounds.width - (sectionSpacing * 2),
height: bodyBounds.height - switchesHeight - sectionSpacing
height: lightsHeight
)
}
if _audioMixerController.parent === self, !_isAudioMixerAnimating {
_audioMixerController.view.frame = _isAudioMixerPresented
? _audioMixerPresentedFrame()
: _audioMixerHiddenFrame()
}
_updateSizeClassPresentation()
}
@@ -214,6 +276,90 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate, Serv
_visualizationController.setPercentActivated(percentageActivated, animated: animated)
}
}
internal func _presentAudioMixer()
{
guard !_isAudioMixerPresented, !_isAudioMixerAnimating else { return }
if _audioMixerController.parent == nil {
addChild(_audioMixerController)
view.addSubview(_audioMixerController.view)
_audioMixerController.didMove(toParent: self)
}
_isAudioMixerPresented = true
_isAudioMixerAnimating = true
_audioMixerDimmingView.alpha = 0.0
_audioMixerDimmingView.isHidden = false
_audioMixerController.view.isHidden = false
_audioMixerController.view.frame = _audioMixerHiddenFrame()
_audioMixerController.view.setNeedsLayout()
_audioMixerController.view.layoutIfNeeded()
view.bringSubviewToFront(_audioMixerDimmingView)
view.bringSubviewToFront(_audioMixerController.view)
UIView.animate(
withDuration: 0.45,
delay: 0.0,
usingSpringWithDamping: 0.88,
initialSpringVelocity: 0.25,
options: [.allowUserInteraction, .beginFromCurrentState],
animations: {
self._audioMixerDimmingView.alpha = 0.55
self._audioMixerController.view.frame = self._audioMixerPresentedFrame()
},
completion: { _ in
self._isAudioMixerAnimating = false
self._audioMixerController.view.frame = self._audioMixerPresentedFrame()
}
)
}
internal func _dismissAudioMixer()
{
guard _isAudioMixerPresented, !_isAudioMixerAnimating else { return }
_isAudioMixerPresented = false
_isAudioMixerAnimating = true
UIView.animate(
withDuration: 0.35,
delay: 0.0,
options: [.curveEaseIn, .allowUserInteraction, .beginFromCurrentState],
animations: {
self._audioMixerDimmingView.alpha = 0.0
self._audioMixerController.view.frame = self._audioMixerHiddenFrame()
},
completion: { _ in
self._isAudioMixerAnimating = false
self._audioMixerController.view.isHidden = true
self._audioMixerDimmingView.isHidden = true
}
)
}
@objc private func _audioMixerDimmingViewTapped()
{
_dismissAudioMixer()
}
private func _audioMixerPresentedFrame() -> CGRect
{
let switchesFrame = _switchesController.view.frame
return CGRect(
x: switchesFrame.minX - AudioMixerViewController.controlsWidth,
y: switchesFrame.minY,
width: switchesFrame.width + AudioMixerViewController.controlsWidth,
height: _audioSectionView.frame.maxY - switchesFrame.minY
)
}
private func _audioMixerHiddenFrame() -> CGRect
{
return _audioMixerPresentedFrame().offsetBy(
dx: UIScreen.main.bounds.width,
dy: 0.0
)
}
internal func _updateConnectivityStatus(_ status: ConnectionStatus)
{