Benjamin RD
Benjamin RD

Reputation: 12034

Call another view using delegates

I have my own Button control, very similar to swift 5.

My protocol:

public protocol RoundedButtonDelegate {
    func click(button:RoundedButton)
}

My control:

public struct RoundedButton : View {
    
    public var text:String = ""
    public var backgroundColor:String = ""
    public var borderColor:String = ""
    public var textColor:String = ""
    public var width:CGFloat = 0
    public var height:CGFloat = 0
    public var fontSize:CGFloat = 0
    public var delegate:RoundedButtonDelegate?
    public var controlId:String = ""
    
    init(id:String = "", text:String, width:CGFloat, height:CGFloat, fontSize:CGFloat = 19, theme: Theme = Theme.light, delegate:RoundedButtonDelegate?) {
        
        if theme == Theme.light {
            self.backgroundColor = LightColorSchema.mainColor.rawValue
            self.borderColor = LightColorSchema.mainText.rawValue
            self.textColor = LightColorSchema.mainText.rawValue
        }
        
        if theme == Theme.dark {
            self.backgroundColor = DarkColorSchema.mainColor.rawValue
            self.borderColor = DarkColorSchema.mainText.rawValue
            self.textColor = DarkColorSchema.mainText.rawValue
        }
        
        self.controlId = id
        self.text = text
        self.width = width
        self.height = height
        self.fontSize = fontSize
        self.delegate = delegate
    }
    
    public var body: some View {
        ZStack {
            Button(action: {
                print(">Redirect to next page")
                self.delegate?.click(button: self)
                
            }) {
                HStack(alignment: .center, spacing: 5.0) {
                    Text(self.text)
                        .font(.custom("Montserrat-SemiBold", size: self.fontSize))
                        .foregroundColor(Color.init(hex: self.textColor))
                        .padding(.all, 10.0)
                }
                //.frame(width: UIScreen.main.bounds.width - 80, height: 48, alignment: .center)
            }
            .padding(.all, 10)
            .frame(width: self.width, height: self.height, alignment: .center)
            .overlay(
                RoundedRectangle(cornerRadius: self.height / 2)
                    .stroke(Color.init(hex: self.borderColor), lineWidth: 1)
            ).background(RoundedRectangle(cornerRadius: 40).fill(Color.init(hex: self.backgroundColor)))
        }
        .frame(width: self.width, height: self.height, alignment: .center)
        
        
    }
    
}

This is not an special control, is just to define some UI componentes. Well, in my view I have the implementation like:

func click(button: RoundedButton) {
        print("Execute protocol")
        switch button.controlId {
        case "btnSesion":
            return
        case "btnTarjeta":
            return self.redirectSeleccionarTarjeta() //Here is accessing!
        default:
            print("No defined action")
        }
    }

And this is the method that I need to solve:

func redirectSeleccionarTarjeta()  {
        print(">Redirect")
        self.showLinkTarget = true
        
        
        //self.navigate(to: InicioSolicitarTarjetaView(), when: $showLinkTarget)
        
            self.fullScreenCover(isPresented: $showLinkTarget, content: {
                InicioSolicitarTarjetaView()
                            })
//        NavigationLink(destination: InicioSolicitarTarjetaView(), isActive: self.$showLinkTarget ) {
//           Spacer().fixedSize()
//        }
    }

How can I redirect to another view from a delegate action? Is that possible? I tried in several ways, but no luck

Upvotes: 1

Views: 166

Answers (1)

jnpdx
jnpdx

Reputation: 52347

Rather than using self.fullScreenCover in your button callback, you need to actually use it in your view hierarchy. Then, just change the showLinkTarget value in your callback. The next time the view is rendered, the fullScreenCover should be presented.

Simplified example:

@State var showWindow = false

Button(action: {
    showWindow.toggle()
}) {
    Text("Open window")
}.fullScreenCover(isPresented: $showWindow, content: {
    Text("Content")
})

Note that this is within the view hierarchy -- not the button's action callback.

See more detailed info about using fullScreenCover: https://www.hackingwithswift.com/quick-start/swiftui/how-to-present-a-full-screen-modal-view-using-fullscreencover

Upvotes: 1

Related Questions