Füllend heisst füllend — der schwarze Streifen unten ist weg

Im Füllmodus wurde die Bildebene unten um den Sicherheitsrand eingerückt,
damit die Untertitel nicht unter die Bildschirmkante geraten. Das stand
dort unbedingt — auch wenn gar kein Untertitel lief. Übrig blieb dann ein
schwarzer Streifen unter einem Bild, das gerade füllen soll: genau das
Gegenteil dessen, wofür der Knopf da ist.

Der Einzug hängt jetzt daran, ob überhaupt eine Untertitelspur gewählt
ist. Ohne Untertitel reicht das Bild bis an alle vier Kanten, mit
Untertiteln bleibt die Schrift gerettet.

Gemessen auf einem Pro Max, füllend, ohne Untertitel:

    hochkant    440 × 956 pt   Rand 0,0 / 0,0 / 0,0 / 0,0
    quer        956 × 440 pt   Rand 0,0 / 0,0 / 0,0 / 0,0

`PlayerModel.subtitleBottomInset` fällt weg. Die Eigenschaft beschrieb
diese Rechnung, las sie aber niemand — die Ansicht rechnete selbst. Eine
Beschreibung, die nichts beschreibt, zeigt beim nächsten Mal in die
falsche Richtung.

**Nicht geprüft:** wie es mit eingeschalteten Untertiteln aussieht. Die
Attrappe liefert keine Untertitelspur, und ohne eine lässt sich der Fall
im Simulator nicht herstellen. Der Weg ist unverändert geblieben, aber
belegt ist er damit nicht.

iOS und tvOS bauen, 463 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-01 07:55:50 +02:00
co-authored by Claude Opus 5
parent 9e7f3393b4
commit 46b0117984
3 changed files with 13 additions and 19 deletions
-9
View File
@@ -188,15 +188,6 @@ final class PlayerModel {
/// `applyVideoFit()`. /// `applyVideoFit()`.
var videoFit: VideoFit = .fit var videoFit: VideoFit = .fit
/// Wie viel unten ausgespart bleibt, damit Untertitel sichtbar sind.
///
/// Im Füllmodus reicht das Bild über die untere Bildschirmkante hinaus —
/// und genau dort zeichnet AVFoundation die Untertitel. Statt sie
/// anzuschneiden, wird die **Bildebene** eingerückt: das kostet rund
/// zwanzig Punkt Bild und behält die Schrift. Im eingepassten Modus ist
/// der Wert null, weil dort ohnehin schwarze Balken liegen.
var subtitleBottomInset: CGFloat = 0
/// Wo das Bild aufhört. /// Wo das Bild aufhört.
/// ///
/// Liegt bei `FlixyPlayback`, weil beide Engines es brauchen. Der Name /// Liegt bei `FlixyPlayback`, weil beide Engines es brauchen. Der Name
+11 -8
View File
@@ -845,14 +845,17 @@ struct PlayerView: View {
engine: model.engine, engine: model.engine,
surface: model.surface, surface: model.surface,
isActive: playback.presentation == .full, isActive: playback.presentation == .full,
// **Nur im Füllmodus.** Eingepasst liegt das Bild seit // **Nur im Füllmodus, und nur wenn ein Untertitel läuft.**
// Neuestem ohnehin im sicheren Bereich — dort kann kein //
// Untertitel mehr unter die Kante geraten. // Füllend reicht das Bild über die untere Bildschirmkante hinaus,
// Im Füllmodus läuft das Bild bis an die Kanten; damit der // und genau dort zeichnet AVFoundation die Untertitel; die Ebene
// Untertitel nicht darunter gerät, wird die **Ebene** unten // unten einzurücken rettet die Schrift. Läuft aber keiner, rettet
// eingerückt. Der rohe Wert genügt hier — es geht um die // es nichts — dann bleibt bloss ein schwarzer Streifen unter
// Bildschirmkante, nicht um die Mitte. // einem Bild, das gerade füllen soll. Das ist das Gegenteil
bottomInset: model.videoFit == .fill ? safeArea.bottom : 0 // dessen, wofür der Knopf da ist.
bottomInset: model.videoFit == .fill && model.selectedSubtitleTrack != nil
? safeArea.bottom
: 0
) )
// **Im Füllmodus kein Seitenverhältnis.** Die Fläche soll den Schirm // **Im Füllmodus kein Seitenverhältnis.** Die Fläche soll den Schirm
+2 -2
View File
@@ -56,8 +56,8 @@ struct VideoSurface: View {
/// Wie viel unten frei bleibt, damit Untertitel nicht abgeschnitten werden. /// Wie viel unten frei bleibt, damit Untertitel nicht abgeschnitten werden.
/// ///
/// Siehe `PlayerModel.subtitleBottomInset`. Hier steht nur die Zahl; was /// Hier steht nur die Zahl; wann sie ungleich null ist, entscheidet
/// sie bedeutet, entscheidet das Modell. /// `PlayerView.surface(for:)`.
var bottomInset: CGFloat = 0 var bottomInset: CGFloat = 0
var body: some View { var body: some View {