最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swiftui - Why is ViewModifier's init method called multiple times? - Stack Overflow

programmeradmin1浏览0评论

I've created a custom navigation bar modifier CustomNavigationBarModifier in SwiftUI, which implements the ViewModifier protocol to standardize the navigation bar style throughout the app. However, I've found that the init method of CustomNavigationBarModifier is being called unexpectedly multiple times, causing some unnecessary repetitive operations.

import SwiftUI

enum Decoration: String {
   case Human
   case Arc
}

enum DestinationType {
   case view(() -> AnyView)
   case action(() -> Void)
}

struct CustomNavigationBarModifier: ViewModifier {
   @Environment(\.dismiss) private var dismiss
   var destination: DestinationType?
   var onButtonClick: (() -> Void)?
   
   init(
      destination: DestinationType? = nil,
      onButtonClick: (() -> Void)? = nil
   ) {
      self.destination = destination
      self.onButtonClick = onButtonClick
      print("Decoration / 28")
   }
   
   func body(content: Content) -> some View {
      content
         .background(Color.clear.ignoresSafeArea(.all))
         .navigationBarBackButtonHidden(true)
         .navigationBarTitleDisplayMode(.inline)
         .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
               Button(action: { dismiss() }) {
                  Image("Back_Arrow")
                     .resizable()
                     .aspectRatio(contentMode: .fit)
                     .frame(width: 35, height: 35)
                     .foregroundStyle(Color("252A3F_FCFCFC"))
               }
            }
         }
         .onAppear{
            print("Decoration / 58")
         }
   }
}

extension View {
   func applyCustomNavigationBar(
      destination: DestinationType? = nil,
      onButtonClick: (() -> Void)? = nil
   ) -> some View {
      self.modifier(CustomNavigationBarModifier(destination: destination, onButtonClick: onButtonClick))
   }
}

print:

Decoration / 28
Decoration / 58
Decoration / 28
Decoration / 28

My questions:

  • Why is the init method of CustomNavigationBarModifier being called multiple times? Considering the way ViewModifier works, is this related to how SwiftUI handles view modifications?
  • How can I avoid the init method being called multiple times to optimize performance? Is there a way to control the initialization timing of ViewModifier?
import SwiftUI

struct SkillsDashboard: View {
   @State private var cardSize: CGSize = .zero
   @State private var showSheet: Bool = false
   
   let skills = ["Swift", "Objective-C", "Kotlin", "Java", "Python", "JavaScript", "Ruby", "C++"]
   
   let columns = [
      GridItem(.flexible(), spacing: 8),
      GridItem(.flexible(), spacing: 8)
   ]
   
   var body: some View {
      ZStack {
         ScrollView {
            Prediction(
               Button(action: {
                  showSheet.toggle()
               },
                      label: {
                         Text("添加技能")
                            .multilineTextStyle(config: (.center, 20, .heavy, "252A3F_0F2534", 1))
                      })
            )
            .padding(.horizontal, 10)
            LazyVGrid(columns: columns, spacing: 8) {
               ForEach(skills, id: \.self) { _ in
                  skillCard()
               }
            }
            
         }
      }
      .padding(.all, 8)
      .background(Color("EFEFF4_0F2534"))
      .sheet(isPresented: $showSheet) {
         VStack(spacing: 0) {
            HStack{}
               .frame(height: 16)
               .padding(0)
            
            LazyVGrids()
            
            HStack(alignment: .center, spacing: 0) {
               Image("AngularBorder")
                  .resizable()
                  .aspectRatio(contentMode: .fill)
                  .foregroundColor(Color("FF5252_FCFCFC"))
                  .frame(width: 34, height: 92)
               
               Spacer()
               
               Image("AngularBorder")
                  .resizable()
                  .aspectRatio(contentMode: .fill)
                  .foregroundColor(Color("FF5252_FCFCFC"))
                  .frame(width: 34, height: 92)
                  .scaleEffect(x: -1, y: 1)
               
            }
            .overlay {
               Button {
                  
               } label: {
                  RoundedRectangle(cornerRadius: 100)
                     .strokeBorder(Color("FF5252_FCFCFC"), lineWidth: 3, antialiased: true)
                     .frame(height: 60)
                     .background(Color("FFE30A_DBD5C9"))
               }
               .padding(.horizontal, 8)
            }
            .padding(.horizontal, 8)
            .padding(.top, -3)
            
            FormSheet()
               .frame(maxWidth: .infinity, alignment: .top)
            
            Spacer()
         }
         .frame(maxHeight: .infinity, alignment: .top)
         .padding(0)
         .presentationCornerRadius(25)
         .background(Color("FFE30A_DBD5C9"))
      }
      .applyCustomNavigationBar()
   }
}
发布评论

评论列表(0)

  1. 暂无评论