When I am trying to add a plus button, which is overlapped on two rows of the list. The code works fine for cases: 1) When view will appear, 2) Scrolling from top to bottom (Every time). However, the code is not working properly when I scroll from bottom of the list to top. After scrolling from bottom to top, the next row is overlapped some part of plus image.
Moreover,I have tried to refresh the plus image by changing foreground color of the image when view appears on the screen. But, it didn't work. Here, I am toggling needRefresh variable of the Card model to refresh the plus image.
struct Card: Identifiable {
var cardNum = 0
var id = UUID()
var needRefresh: Bool = false
init(cardNum: Int) {
self.cardNum = cardNum
}
}
class CardModel: ObservableObject {
@Published var cards = [Card]()
init() {
for val in (1...10) {
let card = Card(cardNum: val)
cards.append(card)
}
}
}
struct ContentView: View {
@StateObject var cardModel = CardModel()
@State var refreshStatus = false
var body: some View {
NavigationView {
List($cardModel.cards) { $card in
CardViewRow(card: $card)
}
.navigationTitle("List")
.navigationBarTitleDisplayMode(.inline)
}
}
}
struct CardViewRow: View {
@Binding var card: Card
var body: some View {
ZStack(alignment: .bottom){
CardView()
Image(systemName: "plus.app.fill")
.font(.system(size: 40.0))
.offset(y: 25)
.foregroundColor(card.needRefresh ? .blue : .red)
.onAppear {
card.needRefresh.toggle()
}
}
}
}
struct CardView: View {
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 25, style: .continuous)
.fill(.white)
.shadow(radius: 10)
VStack {
Text("Question")
.font(.largeTitle)
.foregroundColor(.black)
Text("Answer")
.font(.title)
.foregroundColor(.gray)
}
.padding(20)
.multilineTextAlignment(.center)
}
.frame(width: UIScreen.main.bounds.size.width - 40, height: 150)
}
}
I think it will be tricky with a list, as it "crops" the list cells. But it would work like this with a ScrollView
and LazyVStack
:
struct ContentView: View {
@ObservedObject var cardVM = CardVM()
@State var refreshStatus = false
var body: some View {
NavigationView {
ScrollView {
LazyVStack(spacing: -15) {
ForEach(cardVM.cardList, id: \.id) { card in
CardViewRow(card: card)
}
}
}
.listStyle(.plain)
.navigationTitle("List")
.navigationBarTitleDisplayMode(.inline)
}
}
}
struct CardViewRow: View {
@ObservedObject var card: Card
var body: some View {
CardView()
Image(systemName: "plus.app.fill")
.font(.system(size: 40.0))
.offset(y: 0)
.foregroundColor(card.needRefresh ? .blue : .red)
.zIndex(1)
.onAppear {
card.needRefresh.toggle()
}
}
}