UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Day88: How the callback in CardView work with cards.remove in ContentView?

Forums > SwiftUI

In SwiftUI Day88 Part3, Paul wrote:

So, add this new property to CardView below its existing card property:

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

As you can see, that’s a closure that accepts no parameters and sends nothing back, defaulting to nil so we don’t need to provide it unless it’s explicitly needed.

Now we can replace // remove the card with a call to that closure:

self.removal?()

Tip: That question mark in there means the closure will only be called if it has been set.

Back in ContentView we can now write a method to handle removing a card, then connect it to that closure.

First, add this method that takes an index in our cards array and removes that item:

func removeCard(at index: Int) {
    cards.remove(at: index)
}

I feel challenging to understand this part of description. Would someone help me to understand how cards.remove set self.removal? or how is the mechanism of var removal: (() -> Void)? = nil ?

Thank you very much!

2      

I did more digging, and wonder when is "self.removal" assigned a func ? By adding didSet and willSet, those lines never get printed.

var removal: (() -> Void)? = nil {
    didSet{
        print("DidSet removal")
    }
    willSet{
        print("willSet removal")
    }
}

and the value of self.removalbefore self.removal?()is called in stack view are:

removal (() -> Void)? 0x00000001022922f0 Flashzilla`partial apply forwarder for closure #1 () -> () in closure #1 (Swift.Int) -> SwiftUI.ModifiedContent<<<opaque return type of (extension in SwiftUI):SwiftUI.View.allowsHitTesting(Swift.Bool) -> some>>.0, SwiftUI.AccessibilityAttachmentModifier> in closure #1 () -> SwiftUI.ForEach<Swift.Range<Swift.Int>, Swift.Int, SwiftUI.ModifiedContent<<<opaque return type of (extension in SwiftUI):SwiftUI.View.allowsHitTesting(Swift.Bool) -> some>>.0, SwiftUI.AccessibilityAttachmentModifier>> in closure #1 () -> SwiftUI.TupleView<(SwiftUI.Spacer, <<opaque return type of (extension in SwiftUI):SwiftUI.View.background<A where A1: SwiftUI.View>(: A1, alignment: SwiftUI.Alignment) -> some>>.0, <<opaque return type of (extension in SwiftUI):SwiftUI.View.allowsHitTesting(Swift.Bool) -> some>>.0, Swift.Optional<<<opaque return type of (extension in SwiftUI):SwiftUI.View.clipShape<A where A1: SwiftUI.Shape>(: A1, style: SwiftUI.FillStyle) -> some>>.0>, SwiftUI.ConditionalContent<<<opaque return type of (extension in SwiftUI):SwiftUI.View.padding(SwiftUI.Edge.Set, Swift.Optional<CoreGraphics.CGFloat>) -> some>>.0, SwiftUI.Spacer>)> in closure #1 () -> SwiftUI.TupleView<(<<opaque return type of (extension in SwiftUI):SwiftUI.View.ignoresSafeArea(: SwiftUI.SafeAreaRegions, edges: SwiftUI.Edge.Set) -> some>>.0, <<opaque return type of (extension in SwiftUI):SwiftUI.View.onAppear(perform: Swift.Optional<() -> ()>) -> some>>.0, SwiftUI.VStack<SwiftUI.TupleView<(SwiftUI.HStack<SwiftUI.TupleView<(<<opaque return type of (extension in SwiftUI):SwiftUI.View.actionSheet(isPresented: SwiftUI.Binding<Swift.Bool>, content: () -> SwiftUI.ActionSheet) -> some>>.0, SwiftUI.Spacer, SwiftUI.Button<<<opaque return type of (extension in SwiftUI):SwiftUI.View.padding(SwiftUI.Edge.Set, Swift.Optional<CoreGraphics.CGFloat>) -> some>>.0>)>>, SwiftUI.Spacer)>>)> in Flashzilla.CardsView.body.getter : some at <compiler-generated>``

if removal contains so many values.....how doesself.removal?() call cards.removeCard(at: index)?

2      

It gets set in the trailing closure of the CardView initializer here:

ForEach(0..<cards.count, id: \.self) { index in
    CardView(card: self.cards[index]) {
       withAnimation {
           self.removeCard(at: index)
       }
    }
    .stacked(at: index, in: self.cards.count)
}

Without using a trailing closure, it would look like this, which should make it a bit clearer what's going on:

ForEach(0..<cards.count, id: \.self) { index in
    CardView(card: self.cards[index], removal: {
       withAnimation {
           self.removeCard(at: index)
       }
    })
    .stacked(at: index, in: self.cards.count)
}

4      

@roosterboy

That's all make sense now, thank you very much!

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.