Передача необязательного закрытия в представление

#swift #swiftui #closures

#swift #swiftui #закрытие

Вопрос:

Я создал новое вложенное представление, содержащее заголовок для других представлений. У него есть значок со стрелкой, и я хочу передать закрытие этому подвиду (profileClose — это функция):

 PlainHeader(title: getLocalizedText("edit profile"), action: profileClose) 
 

Проблема в том, что я хочу, чтобы это закрытие было необязательным.. Поэтому я решил обернуть его в () ? = nil , но после того, как я делал это каждый раз, когда я использую PlainHeader(...) . Xcode говорит "Extra argument 'action' in call"

 import SwiftUI

struct PlainHeader: View {
    var title: String
    let action: (() -> Void)? = nil
    
    var body: some View {
        
        VStack(spacing: 0) {
                        
            ZStack {
                
                VStack(spacing: 0) {
                    HStack {
                        Image("arrow-back")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 18, height: 7)
                            .padding(.leading, 31)
                        Spacer()
                    }
                    .onTapGesture {
                        print("[debugUI] action called")
                        if self.action != nil {
                            self.action!()
                        }
                    }
                }
                VStack {
                    HStack {
                        Text("(title)")
                            .lineLimit(nil)
                            .multilineTextAlignment(.center)
                            .frame(maxWidth: 280)
                            .font(.custom(Font.primaryTextFont, size: 20))
                            .foregroundColor(Color.mainSubtitleColor)
                    }
                }
                
            }
            .padding(.top, 20)
        }
        .frame(height: 80)
        
    }
}
 

Что я делаю не так? Я просто хочу использовать его с закрытием и без него.. поэтому я установил его как необязательный и присвоил ему значение по умолчанию nil..

Ответ №1:

Измените переменную let на var.

 var action: (() -> Void)? = nil
 

Ответ №2:

Проблемы здесь:

 let action: (() -> Void)? = nil
 

Вы объявили его как let и мгновенно установили для nil него значение, поэтому оно недоступно для повторной инициализации.

Вы можете либо объявить его как var , либо, что еще лучше, написать инициализатор:

 struct PlainHeader: View {
    private let title: String
    private let action: (() -> Void)?

    public init(title: String,
                action: (() -> Void)? = nil) {
        self.title = title
        self.action = action
    }
    //etc.
}
 

Комментарии:

1. @ LuLuGaGa: почему вы использовали «публичный инициализирующий»? я думаю, что один «init» выполняет свою работу. дайте мне знать, почему или чего мне не хватает?

2. инициализация тоже в порядке.