iosswiftuioverlaylazyvgrid

How to Get the Size of the GrideItem View in LazyVGrid or Showing a Number Near the Corner of a View


I have a bunch of Buttons in LazyVGrid as shown in the picture below. I want to show a number near the top-left corner of a button. For a particular iOS device model, I can just offset the position of a number. But this approach can be terribly wrong if I have an iPad. Is there a way of getting the size of the GridItem View? If there isn't, is there an effective way of showing a number near the top-left corner regardless of the device model? Thanks.

enter image description here

import SwiftUI

struct ContentView: View {
    private let cols = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible())
    ]
    
    var body: some View {
        LazyVGrid(columns: cols) {
            ForEach(0...30, id: \.self) { item in
                Button {
                    
                } label: {
                    Image(systemName: "\(item).circle.fill")
                         .resizable()
                         .aspectRatio(contentMode: .fit)
                         .foregroundColor(.orange)
                    
                }
                .overlay {
                    Text("0")
                        .font(.caption)
                        .foregroundStyle(.blue)
                        .offset(x: -20, y: -20)
                }
            }
        }
    }
}

Solution

  • The overlay modifier takes an alignment argument which defaults to .center. Try passing .topLeading instead of using .offset:

    Button { } label: {
        Image(systemName: "\(item).circle.fill")
             .resizable()
             .aspectRatio(contentMode: .fit)
             .foregroundColor(.orange)
        
    }
    .overlay(alignment: .topLeading) {
    //       ^^^^^^^^^^^^^^^^^^^^^^ 🟢 ADD THIS
        Text("0")
            .font(.caption)
            .foregroundStyle(.blue)
    }