mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Use a UIViewRepresentable to set slider images instead of introspection
The slider was losing the custom images when being opened/closed sometimes because introspection doesn't get called.
This commit is contained in:
parent
d77f893e06
commit
8e1ac67d80
2 changed files with 84 additions and 27 deletions
|
|
@ -192,11 +192,11 @@ public struct MiniPlayer: View {
|
|||
|
||||
if !expanded {
|
||||
Text(itemAudioProperties.title)
|
||||
.font(expanded ? .appTitle : .appCallout)
|
||||
.font(.appCallout)
|
||||
.lineSpacing(1.25)
|
||||
.foregroundColor(.appGrayTextContrast)
|
||||
.fixedSize(horizontal: false, vertical: false)
|
||||
.frame(maxWidth: .infinity, alignment: expanded ? .center : .leading)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.matchedGeometryEffect(id: "ArticleTitle", in: animation)
|
||||
|
||||
playPauseButtonItem
|
||||
|
|
@ -221,31 +221,15 @@ public struct MiniPlayer: View {
|
|||
.foregroundColor(.appGrayText)
|
||||
}
|
||||
|
||||
Slider(value: $audioController.timeElapsed,
|
||||
in: 0 ... self.audioController.duration,
|
||||
onEditingChanged: { scrubStarted in
|
||||
if scrubStarted {
|
||||
self.audioController.scrubState = .scrubStarted
|
||||
} else {
|
||||
self.audioController.scrubState = .scrubEnded(self.audioController.timeElapsed)
|
||||
}
|
||||
})
|
||||
.accentColor(.appCtaYellow)
|
||||
.introspectSlider { slider in
|
||||
// Make the thumb a little smaller than the default and give it the CTA color
|
||||
// for some reason this doesn't work on my iPad though.
|
||||
let tintColor = UIColor(Color.appCtaYellow)
|
||||
|
||||
let image = UIImage(systemName: "circle.fill",
|
||||
withConfiguration: UIImage.SymbolConfiguration(scale: .small))?
|
||||
.withTintColor(tintColor)
|
||||
.withRenderingMode(.alwaysOriginal)
|
||||
|
||||
slider.setThumbImage(image, for: .selected)
|
||||
slider.setThumbImage(image, for: .normal)
|
||||
|
||||
slider.minimumTrackTintColor = tintColor
|
||||
}
|
||||
ScrubberView(value: $audioController.timeElapsed,
|
||||
minValue: 0, maxValue: self.audioController.duration,
|
||||
onEditingChanged: { scrubStarted in
|
||||
if scrubStarted {
|
||||
self.audioController.scrubState = .scrubStarted
|
||||
} else {
|
||||
self.audioController.scrubState = .scrubEnded(self.audioController.timeElapsed)
|
||||
}
|
||||
})
|
||||
|
||||
HStack {
|
||||
Text(audioController.timeElapsedString ?? "0:00")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// ScrubberView.swift
|
||||
//
|
||||
//
|
||||
// Created by Jackson Harper on 9/27/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct ScrubberView: UIViewRepresentable {
|
||||
typealias UIViewType = UISlider
|
||||
|
||||
@Binding var value: Double
|
||||
var minValue: Double
|
||||
var maxValue: Double
|
||||
var onEditingChanged: (Bool) -> Void
|
||||
|
||||
init(value: Binding<Double>, minValue: Double, maxValue: Double, onEditingChanged: @escaping (Bool) -> Void) {
|
||||
self._value = value
|
||||
self.minValue = minValue
|
||||
self.maxValue = maxValue
|
||||
self.onEditingChanged = onEditingChanged
|
||||
}
|
||||
|
||||
func makeUIView(context: Context) -> UISlider {
|
||||
let slider = UISlider(frame: .zero)
|
||||
slider.maximumValue = Float(minValue)
|
||||
slider.maximumValue = Float(maxValue)
|
||||
|
||||
let tintColor = UIColor(Color.appCtaYellow)
|
||||
|
||||
let image = UIImage(systemName: "circle.fill",
|
||||
withConfiguration: UIImage.SymbolConfiguration(scale: .small))?
|
||||
.withTintColor(tintColor)
|
||||
.withRenderingMode(.alwaysOriginal)
|
||||
|
||||
slider.setThumbImage(image, for: .selected)
|
||||
slider.setThumbImage(image, for: .normal)
|
||||
|
||||
slider.minimumTrackTintColor = tintColor
|
||||
slider.addTarget(context.coordinator,
|
||||
action: #selector(Coordinator.valueChanged(_:)),
|
||||
for: .valueChanged)
|
||||
|
||||
return slider
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UISlider, context _: Context) {
|
||||
uiView.value = Float(value)
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
let coordinator = Coordinator(value: $value, onEditingChanged: onEditingChanged)
|
||||
return coordinator
|
||||
}
|
||||
|
||||
class Coordinator: NSObject {
|
||||
var value: Binding<Double>
|
||||
var onEditingChanged: (Bool) -> Void
|
||||
|
||||
init(value: Binding<Double>, onEditingChanged: @escaping (Bool) -> Void) {
|
||||
self.value = value
|
||||
self.onEditingChanged = onEditingChanged
|
||||
super.init()
|
||||
}
|
||||
|
||||
@objc func valueChanged(_ sender: UISlider) {
|
||||
value.wrappedValue = Double(sender.value)
|
||||
onEditingChanged(sender.isTracking)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue