SwiftUI-를 사용하여 변수 계산 내에서 ForEach

0

질문

내가 만든 뷰를 통해 ForEach 루프는 필요한 변수 계산 내에서 ForEach 자체 즉 나는 응용 프로그램을 필요로 반응하는 동적 계산과 변경 UI accoridngly.

여기에는 나을 수정하려고 하:

struct AnimatedTabSelector: View {
    let buttonDimensions: CGFloat
    @ObservedObject var tabBarViewModel: TabBarViewModel
    
    var body: some View {
        HStack {
            Spacer().frame(maxWidth: .infinity).frame(height: 20)
                .background(Color.red)
            
            ForEach(1..<tabBarViewModel.activeFormIndex + 1) { _ in
                Spacer().frame(maxWidth: buttonDimensions).frame(height: 20)
                    .background(Color.blue)
                Spacer().frame(maxWidth: .infinity).frame(height: 20)
                    .background(Color.green)
            }
            
            Circle().frame(
                width: buttonDimensions,
                height: buttonDimensions)
                .foregroundColor(
                    tabBarViewModel.activeForm.loginFormViewModel.colorScheme
                )
            
            ForEach(1..<tabBarViewModel.loginForms.count - tabBarViewModel.activeFormIndex) { _ in
                Spacer().frame(maxWidth: .infinity).frame(height: 20)
                    .background(Color.red)
                Spacer().frame(maxWidth: buttonDimensions).frame(height: 20)
                    .background(Color.blue)
            }
            
            Spacer().frame(maxWidth: .infinity).frame(height: 20)
                .background(Color.gray)
        }
    }
}

고 뷰 모델을 관찰할 것입니다:

class TabBarViewModel: ObservableObject, TabBarCompatible {
    var loginForms: [LoginForm]
    @Published var activeForm: LoginForm
    @Published var activeFormIndex = 0
    private var cancellables = Set<AnyCancellable>()
    
    init(loginForms: [LoginForm]) {
        self.loginForms = loginForms
        self.activeForm = loginForms[0] /// First form is always active to begin
        setUpPublisher()
    }
    
    func setUpPublisher() {
        for i in 0..<loginForms.count {
            loginForms[i].loginFormViewModel.$isActive.sink { isActive in
                if isActive {
                    self.activeForm = self.loginForms[i]
                    self.activeFormIndex = i
                }
            }
            .store(in: &cancellables)
        }
    }
}

마지막으로 loginFormViewModel:

class LoginFormViewModel: ObservableObject {
    @Published var isActive: Bool
    
    let name: String
    let icon: Image
    let colorScheme: Color
    
    init(isActive: Bool = false, name: String, icon: Image, colorScheme: Color) {
        self.isActive = isActive
        self.name = name
        self.icon = icon
        self.colorScheme = colorScheme
    }
}

기본적으로,버튼을에서 로그인 형태 그 자체를 설정 시점의 isActive 속성을 true 로 설정할 수 있습니다. 우리는 듣는 이를 위해서 TabBarViewModel 설정 activeFormIndex 니다. 이 인덱스는 다음에 사용되는 ForEach 다. 기본적으로,에 따라 선택하는 인덱스,내가 생성 할 필요가 더 많거나 적은 간격 장치에서 AnimatedTabSelector 보기입니다.

그러나 하 activeIndex 변수되고 올바르게 업데이트 ForEach 보이지 않는 반응합니다.

업데이트:

이 AnimatedTabSelector 선언의 일환으로 이 전반적인 보기:

struct TabIconsView: View {
    
    struct Constants {
        static let buttonDimensions: CGFloat = 50
        static let buttonIconSize: CGFloat = 25
        static let activeButtonColot = Color.white
        static let disabledButtonColor = Color.init(white: 0.8)
        
        struct Animation {
            static let stiffness: CGFloat = 330
            static let damping: CGFloat = 22
            static let velocity: CGFloat = 7
        }
    }
    
    @ObservedObject var tabBarViewModel: TabBarViewModel
    
    var body: some View {
        ZStack {
            AnimatedTabSelector(
                buttonDimensions: Constants.buttonDimensions,
                tabBarViewModel: tabBarViewModel)
            
            HStack {
                Spacer()
                
                ForEach(tabBarViewModel.loginForms) { loginForm in
                    Button(action: {
                        loginForm.loginFormViewModel.isActive = true
                    }) {
                        loginForm.loginFormViewModel.icon
                            .font(.system(size: Constants.buttonIconSize))
                            .foregroundColor(
                                tabBarViewModel.activeForm.id == loginForm.id ? Constants.activeButtonColot : Constants.disabledButtonColor
                            )
                    }
                    .frame(width: Constants.buttonDimensions, height: Constants.buttonDimensions)
                    Spacer()
                }
            }
        }
        .animation(Animation.interpolatingSpring(
            stiffness: Constants.Animation.stiffness,
            damping: Constants.Animation.damping,
            initialVelocity: Constants.Animation.velocity)
        )
    }
}

업데이트:

나는 또 다른 방법을 시도 추가하여 다른 게시 AnimatedTabSelector 자체를 확인하는 값은 실제로 업데이트되고 있습니다. 그래서 끝에 HStack 이 보기에 추가했:

.onAppear {
            tabBarViewModel.$activeFormIndex.sink { index in
                self.preCircleSpacers = index + 1
                self.postCircleSpacers = tabBarViewModel.loginForms.count - index
            }
            .store(in: &cancellables)
        }

물론 추가하기 위해 다음과 같은 변수를 이기:

@State var preCircleSpacers = 1
@State var postCircleSpacers = 6
@State var cancellables = Set<AnyCancellable>()

다음 ForEach 루프가 변경:

ForEach(1..<preCircleSpacers)

ForEach(1..<postCircleSpacers)

각각합니다.

추가 브레이크 포인트에서 새로운 게시자가 선언하고 그것은 참으로 업데이트되고 있으로 예상된 수치입니다. 그러나보기는 여전히 실패한 변화를 반영하는 값

combine swift swiftui
2021-11-23 22:03:33
1

최고의 응답

0

OK 그래서 나는 것을 발견했 솔루션-나가 추정하는 ForEach 범위를 포함하는 업데이트 하지 않는 동적으로 같은 방법으로는 ForEach 배열을 포함하고 있는 개체는 않습니다.

그래서 오히려 보다:

ForEach(0..<tabBarViewModel.loginForms.count)

etc.

나는 그것을 변경하기:

ForEach(tabBarViewModel.loginForms.prefix(tabBarViewModel.activeFormIndex))

이 방법은 내가 여전히 반복하여 필요한 횟수만 ForEach 업데이트를 동적으로 올바른 숫자의 배열의 항목

2021-11-23 23:51:48

처럼 보이는 문서 가 말하는 많:"는 인스턴스를 읽기만의 초기 값을 데이터를 제공하고 필요가 없을 식별하 전망에 걸쳐 업데이트됩니다. 계산망을 통해 수요에 동적 범위,사용 ForEach/init(_:id:콘텐츠:)."
Charles A.

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................