fix(iOS): 修复视频显示模式为填充

将远端视频渲染视图和内容视图的视频内容模式从 `.fit` 改为 `.fill`,并调整控制面板布局,将录制与断开按钮单独成行,提升界面利用率与操作体验。
This commit is contained in:
2026-08-01 04:04:19 +08:00
parent a73f61f366
commit 2cac572702
2 changed files with 60 additions and 50 deletions

View File

@@ -156,64 +156,72 @@ private struct ControlPanelView: View {
} }
private var topBar: some View { private var topBar: some View {
ScrollView(.horizontal, showsIndicators: false) { VStack(spacing: 6) {
HStack(spacing: 12) { // + + +
Text(viewModel.statusText) ScrollView(.horizontal, showsIndicators: false) {
.font(.footnote) HStack(spacing: 12) {
.foregroundColor(.green) Text(viewModel.statusText)
.lineLimit(1) .font(.footnote)
.foregroundColor(.green)
.lineLimit(1)
.fixedSize()
// WebRTC /
Toggle(isOn: Binding(
get: { viewModel.streamMode == .selfCodec },
set: { viewModel.toggleStreamMode($0) })) {
Text("自编码")
.font(.footnote)
.foregroundColor(.white)
}
.toggleStyle(.switch)
.fixedSize() .fixedSize()
// WebRTC / //
Toggle(isOn: Binding( Menu {
get: { viewModel.streamMode == .selfCodec }, ForEach(ResolutionOption.all) { option in
set: { viewModel.toggleStreamMode($0) })) { Button {
Text("自编码") viewModel.selectResolution(option)
.font(.footnote) } label: {
.foregroundColor(.white) if option == viewModel.selectedResolution {
} Label(option.title, systemImage: "checkmark")
.toggleStyle(.switch) } else {
.fixedSize() Text(option.title)
}
//
Menu {
ForEach(ResolutionOption.all) { option in
Button {
viewModel.selectResolution(option)
} label: {
if option == viewModel.selectedResolution {
Label(option.title, systemImage: "checkmark")
} else {
Text(option.title)
} }
} }
} label: {
Label(viewModel.selectedResolution.title, systemImage: "rectangle.compress.vertical")
.font(.footnote)
.fixedSize()
} }
} label: {
Label(viewModel.selectedResolution.title, systemImage: "rectangle.compress.vertical")
.font(.footnote)
.fixedSize()
}
// REPORT_RESOLUTION // REPORT_RESOLUTION
Menu { Menu {
ForEach(viewModel.fpsOptions, id: \.self) { fps in ForEach(viewModel.fpsOptions, id: \.self) { fps in
Button { Button {
viewModel.selectFps(fps) viewModel.selectFps(fps)
} label: { } label: {
if fps == viewModel.currentFps { if fps == viewModel.currentFps {
Label("\(fps)fps", systemImage: "checkmark") Label("\(fps)fps", systemImage: "checkmark")
} else { } else {
Text("\(fps)fps") Text("\(fps)fps")
}
} }
} }
} label: {
Label(viewModel.currentFps > 0 ? "\(viewModel.currentFps)fps" : "帧率",
systemImage: "speedometer")
.font(.footnote)
.fixedSize()
} }
} label: {
Label(viewModel.currentFps > 0 ? "\(viewModel.currentFps)fps" : "帧率",
systemImage: "speedometer")
.font(.footnote)
.fixedSize()
} }
.padding(.horizontal, 12)
.padding(.vertical, 6)
}
// +
HStack(spacing: 12) {
// MP4 // MP4
Button { Button {
if viewModel.isRecording { if viewModel.isRecording {
@@ -241,9 +249,11 @@ private struct ControlPanelView: View {
.buttonStyle(.borderedProminent) .buttonStyle(.borderedProminent)
.tint(.red) .tint(.red)
.controlSize(.small) .controlSize(.small)
Spacer()
} }
.padding(.horizontal, 12) .padding(.horizontal, 12)
.padding(.vertical, 6) .padding(.bottom, 6)
} }
.background(Color(white: 0.1)) .background(Color(white: 0.1))
} }
@@ -269,7 +279,7 @@ private struct ControlPanelView: View {
viewModel.sendSwipe(x1: x1, y1: y1, x2: x2, y2: y2, duration: duration) viewModel.sendSwipe(x1: x1, y1: y1, x2: x2, y2: y2, duration: duration)
}) })
} }
.aspectRatio(viewModel.videoAspect, contentMode: .fit) .aspectRatio(viewModel.videoAspect, contentMode: .fill)
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
// //

View File

@@ -7,7 +7,7 @@ struct RemoteVideoView: UIViewRepresentable {
let videoView: RTCMTLVideoView let videoView: RTCMTLVideoView
func makeUIView(context: Context) -> RTCMTLVideoView { func makeUIView(context: Context) -> RTCMTLVideoView {
videoView.videoContentMode = .scaleAspectFit videoView.videoContentMode = .scaleAspectFill
return videoView return videoView
} }