Search code examples
swiftuilazyvgrid

Weird gap in LazyVGrid


I'm not very experienced with LazyVGrid. What is this weird gap between the 1:45 and 2:00 buttons, and how can I get rid of it?

import PlaygroundSupport
import SwiftUI

struct ContentView: View {
  
  let dates: [Date] = (0...34).compactMap { interval -> Date? in
    var components = Calendar.current.dateComponents([.day, .month, .year], from: Date())
    components.hour = 7
    components.minute = 30
    
    guard var date = Calendar.current.date(from: components) else { return nil }
    
    date.addTimeInterval(Double(900 * interval))
    
    if Calendar.current.component(.hour, from: date) == 12 {
      date.addTimeInterval(3600)
    }
    
    return date
  }
  
  func text(for date: Date) -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "h:mm a"
    return formatter.string(from: date)
  }
  
  var body: some View {
    LazyVGrid(columns: Array(repeating: GridItem.init(.flexible(), spacing: nil, alignment: nil), count: 3)) {
      ForEach(dates, id: \.self) { date in
        Button {
          
        } label: {
          Capsule()
            .overlay {
              Text(text(for: date))
                .foregroundStyle(.white)
            }
            .foregroundColor(.blue)
            .frame(height: 44)
        }
      }
    }.padding()
  }
}

PlaygroundPage.current.setLiveView(ContentView().frame(width: 400, height: 800).padding())

enter image description here


Solution

  • The problem is that your logic for skipping the 12 o'clock hour time slots is resulting in 4 duplicate dates. You need a collection with only unique values.

    In the dates property initializer, replace the line:

    date.addTimeInterval(3600)
    

    with:

    return nil
    

    This will eliminate the 4 12 o'clock time slots and avoid any duplicate dates which in turn removes the gap in the grid.