Dreamio turn document
+Improve Center Play/Pause Indicator Contrast
+Improved the native player center play/pause flash so it remains visible over varied video content.
+ +Summary
+Improved the native player center play/pause flash so it remains visible over varied video content.
+Changes Made
+-
+
- Made the center play/pause flash larger, darker, and more defined with a stronger border and shadow. +
- Kept the indicator visible for longer during the flash animation and added a reduced-motion fade path. +
Context
+The center-screen play/pause indicator was too transparent, making it hard to see against bright or busy video frames.
+Important Implementation Details
+-
+
- The existing Liquid Glass-style icon button remains in use, but the transient center instance now gets a high-contrast black backing instead of the low-alpha shared control treatment. +
- The hit target and visual footprint increased from 68 to 80 points while keeping the indicator centered. +
- Reduced Motion users now still receive a non-scaling visible flash instead of skipping the indicator entirely. +
Relevant Diff Snippets
+Dreamio/NativePlayerViewController.swift · center play/pause indicator contrast
++343 unmodified lines34434534634734834935064 unmodified lines415416417418419420421422404 unmodified lines827828829830831832833834835836837838839343 unmodified linesaudioButton.showsMenuAsPrimaryAction = truecaptionsButton.showsMenuAsPrimaryAction = trueplayPauseButton.layer.cornerRadius = 28centerPlayPauseButton.layer.cornerRadius = 34centerPlayPauseButton.alpha = 0scrubber.addTarget(self, action: #selector(scrubbingStarted), for: .touchDown)scrubber.addTarget(self, action: #selector(scrubberChanged), for: .valueChanged)64 unmodified lines+centerPlayPauseButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),centerPlayPauseButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),centerPlayPauseButton.widthAnchor.constraint(equalToConstant: 68),centerPlayPauseButton.heightAnchor.constraint(equalToConstant: 68),+closeButton.widthAnchor.constraint(equalToConstant: 44),closeButton.heightAnchor.constraint(equalToConstant: 44),404 unmodified lines+private func flashCenterPlayPauseIcon() {centerPlayPauseButton.setImage(UIImage(systemName: backend.isPlaying ? "pause.fill" : "play.fill"), for: .normal)guard !UIAccessibility.isReduceMotionEnabled else { return }centerPlayPauseButton.transform = CGAffineTransform(scaleX: 0.86, y: 0.86)UIView.animate(withDuration: 0.16, animations: {self.centerPlayPauseButton.alpha = 1self.centerPlayPauseButton.transform = .identity}) { _ inUIView.animate(withDuration: 0.22, delay: 0.28, options: [.curveEaseOut]) {self.centerPlayPauseButton.alpha = 0}}343 unmodified lines34434534634734834935035135235335435535635764 unmodified lines422423424425426427428429404 unmodified lines834835836837838839840841842843844845846847848849850851852853343 unmodified linesaudioButton.showsMenuAsPrimaryAction = truecaptionsButton.showsMenuAsPrimaryAction = trueplayPauseButton.layer.cornerRadius = 28centerPlayPauseButton.layer.cornerRadius = 40centerPlayPauseButton.backgroundColor = UIColor.black.withAlphaComponent(0.58)centerPlayPauseButton.layer.borderColor = UIColor.white.withAlphaComponent(0.38).cgColorcenterPlayPauseButton.layer.borderWidth = 1.5centerPlayPauseButton.layer.shadowColor = UIColor.black.cgColorcenterPlayPauseButton.layer.shadowOpacity = 0.45centerPlayPauseButton.layer.shadowRadius = 18centerPlayPauseButton.layer.shadowOffset = CGSize(width: 0, height: 8)centerPlayPauseButton.alpha = 0scrubber.addTarget(self, action: #selector(scrubbingStarted), for: .touchDown)scrubber.addTarget(self, action: #selector(scrubberChanged), for: .valueChanged)64 unmodified lines+centerPlayPauseButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),centerPlayPauseButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),centerPlayPauseButton.widthAnchor.constraint(equalToConstant: 80),centerPlayPauseButton.heightAnchor.constraint(equalToConstant: 80),+closeButton.widthAnchor.constraint(equalToConstant: 44),closeButton.heightAnchor.constraint(equalToConstant: 44),404 unmodified lines+private func flashCenterPlayPauseIcon() {centerPlayPauseButton.setImage(UIImage(systemName: backend.isPlaying ? "pause.fill" : "play.fill"), for: .normal)if UIAccessibility.isReduceMotionEnabled {centerPlayPauseButton.transform = .identitycenterPlayPauseButton.alpha = 1UIView.animate(withDuration: 0.18, delay: 0.55, options: [.curveEaseOut]) {self.centerPlayPauseButton.alpha = 0}return}centerPlayPauseButton.transform = CGAffineTransform(scaleX: 0.82, y: 0.82)UIView.animate(withDuration: 0.16, animations: {self.centerPlayPauseButton.alpha = 1self.centerPlayPauseButton.transform = .identity}) { _ inUIView.animate(withDuration: 0.26, delay: 0.34, options: [.curveEaseOut]) {self.centerPlayPauseButton.alpha = 0}}
+ Diffs are generated with @pierre/diffs/ssr at documentation time. Each file diff stays inside its own shell so the page remains readable as a static HTML artifact.
Expected Impact for End-Users
+Users should be able to quickly confirm play or pause state changes from the middle of the screen, even over bright scenes or high-motion content.
+Validation
+-
+
xcodebuild -workspace Dreamio.xcworkspace -scheme Dreamio -sdk iphonesimulator -configuration Debug build— succeeded.
+
Issues, Limitations, and Mitigations
+-
+
- No known issues. This is a visual contrast adjustment scoped to the native player overlay. +
New Changes as of 2026-05-26 22:22
+Summary of changes
+Softened the center play/pause flash from a black badge with a strong outline into a separate liquid-glass blur plate behind a clear icon button.
+Why this change was made
+The previous contrast fix made the transient center indicator visible, but overcorrected with a heavy black fill and outline. The revised treatment keeps the indicator readable while better matching the native Liquid Glass direction.
+Code diffs
++ private let centerPlayPauseIndicator = NativePlayerViewController.centerGlassIndicator()
+...
++ view.addSubview(centerPlayPauseIndicator)
+ view.addSubview(centerPlayPauseButton)
+...
+- centerPlayPauseButton.backgroundColor = UIColor.black.withAlphaComponent(0.58)
+- centerPlayPauseButton.layer.borderColor = UIColor.white.withAlphaComponent(0.38).cgColor
+- centerPlayPauseButton.layer.borderWidth = 1.5
++ centerPlayPauseButton.backgroundColor = .clear
++ centerPlayPauseButton.layer.borderWidth = 0
++ centerPlayPauseIndicator.alpha = 0
+...
++ private static func centerGlassIndicator() -> UIVisualEffectView {
++ let view = glassPanel(cornerRadius: 34)
++ view.backgroundColor = UIColor.white.withAlphaComponent(0.08)
++ view.layer.borderColor = UIColor.white.withAlphaComponent(0.18).cgColor
++ view.layer.borderWidth = 0.75
++ view.isUserInteractionEnabled = false
++ return view
++ }
+ Related issues or PRs
+No new Beads issue or PR was created for this small visual follow-up.
+Follow-up Work
+-
+
- None currently identified. +