There is a toolbar button to change the viewStyle in ContentView.
When the viewStyle is changed, MyPage will regenerate the List based on the viewStyle. However, after generation, the distance between this List and the navigationTitle will automatically increase. Additionally, the navigationTitle originally scrolled with the List, but after changing the viewStyle, it will remain stationary.
What went wrong? Thanks.
import SwiftUI
struct ContentView: View {
@State private var viewStyle: ViewStyle = .bold
var body: some View{
NavigationView {
TabView {
MyPage(viewStyle: $viewStyle)
.tabItem {
Label("Today", systemImage: "1.square.fill")
}
.tag(0)
}
.navigationTitle("title")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
viewStyle = viewStyle.next
}) {
Image(systemName: "pencil")
}
}
}
}
}
}
struct MyPage: View {
@Binding var viewStyle: ViewStyle
var body: some View {
switch viewStyle {
case .bold:
List{
ForEach(0..<4, id: \.self){ index in
VStack{
Label("bold", systemImage: "pencil")
}
}
}
default:
List{
ForEach(0..<3, id: \.self){ index in
VStack{
Label("italic", systemImage: "pencil")
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
enum ViewStyle{
case bold
case italic
var next: ViewStyle{
switch self {
case .bold: return .italic
case .italic: return .bold
}
}
}
This happens when you replace the List
. Try keeping the List
and just replace the content:
struct MyPage: View {
@Binding var viewStyle: ViewStyle
var body: some View {
List { // 👈 Move this out here
switch viewStyle {
case .bold:
ForEach(0..<4, id: \.self){ index in
VStack{
Label("bold", systemImage: "pencil")
}
}
default:
ForEach(0..<3, id: \.self){ index in
VStack{
Label("italic", systemImage: "pencil")
}
}
}
}
}
}
Always try to minimize changes to prevent unexpected rendering and behavior. For example, here you could have just changed the title and count instead of the whole list! Something roughly like this:
struct MyPage: View {
@Binding var viewStyle: ViewStyle
var range: Range<Int> {
switch viewStyle {
case .bold: (0..<4)
default: (0..<3)
}
}
var title: LocalizedStringKey {
switch viewStyle {
case .bold: "bold"
default: "italic"
}
}
var body: some View {
List {
ForEach(range, id: \.self) { index in
VStack {
Label(title, systemImage: "pencil")
}
}
}
}
}