如何在SwiftUI tvOS中实现左侧垂直TabView并避免主视图重绘?
问题:避免垂直Tab切换时主视图重绘并实现对应功能
当TabButton获得焦点时,需在RightMainView展示对应内容。使用ViewModel的@Published属性可实现该功能,但切换标签时RightMainView会重绘。由于主视图是复杂UI且包含焦点引擎,因此绝对不希望其重绘。
已尝试的方案
- 原生TabView:切换标签时视图不会重绘,但仅支持横向布局,不支持左侧垂直模式,询问能否用其实现带文字和图片的垂直TabView;
- NavigationSplitView:在tvOS上的表现与iPad不同,仅显示TabButtons,主视图/详情视图不显示。
相关代码
import SwiftUI struct Model: Identifiable, Equatable { let id = UUID() let title: String static func == (lhs: Model, rhs: Model) -> Bool { return lhs.title == rhs.title } } class ViewModel: ObservableObject { let titles = [Model(title: "Home"), Model(title: "live"), Model(title: "setting"), Model(title: "network")] @Published var selected: Model = Model(title: "Home") } struct ContentView: View { @ObservedObject var viewModel = ViewModel() var body: some View { HStack(spacing: 0) { leftTab .focusSection() rightMainView }.edgesIgnoringSafeArea(.all) } private var leftTab: some View { VStack { ForEach(viewModel.titles, id: \.self.id) { title in ZStack { TabButton(viewModel: viewModel, title: title) }.focusable() } } .frame(maxWidth: 400, maxHeight: .infinity) .background(.yellow) } private var rightMainView: some View { VStack { let _ = print("Redrawing the View") Text(viewModel.selected.title) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.red) } } } struct TabButton: View { @Environment(\.isFocused) var isFocused let viewModel: ViewModel let title: Model var body: some View { Text(title.title) .frame(width: 200) .padding(30) .background(isFocused ? .orange : .white) .foregroundColor(isFocused ? .black : .gray) .cornerRadius(20) .onChange(of: isFocused) { newValue in if newValue { viewModel.selected = title } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
内容的提问来源于stack exchange,提问作者zijia
相关产品推荐
相关产品推荐

