You could sample the random crop size once for the next batch and resample in each iteration of your DataLoader.
Maybe not the most elegant approach, but should do the job.
Here is a small dummy example:
class MyDataset(Dataset):
    def __init__(self, limit):
        self.data = [TF.to_pil_image(x) for x in torch.randn(64, 3, 24, 24)]
        self.limit = limit
        self.resample_size(0)

    def resample_size(self, index):
        size = torch.empty(2).uniform_(self.limit[0], self.limit[1]).long().tolist()
        self.crop_coord = transforms.RandomCrop.get_params(self.data[index], size)
    
    def __getitem__(self, index):
        i, j, h, w = self.crop_coord
        img = self.data[index]
        img = TF.crop(img, i, j, h, w)
        x = TF.to_tensor(img)
        return x
    
    def __len__(self):
        return len(self.data)


dataset = MyDataset(limit=[18, 22])
loader = DataLoader(
    dataset,
    batch_size=4
)


for data in loader:
    loader.dataset.resample_size(0)
    print(data.shape)