It vastly depends on your coders. Some need to be assigned tasks, others are only productive when they actually choose their tasks.
It also depends on the tasks: keep in mind that at some point you'll need to assign a few tasks that nobody will want to do, but which still need to get done.
One thing to do is to have a reasonably complete list of tasks. Give some flexibility to your team members, in the sense that they should be allowed to split, when they feel it necessary, some tasks into smaller, bite-sized subtasks. This will give them a highly increased sense of having a say on what they're going to code.
On this list, make sure it's clear who is assigned which task, and which tasks depend on other tasks. If one task is needed to complete other tasks, it needs to be clear to everyone who to help or nag (depending on whether the assignee is working or not).
As much as possible, you want your coders to commit to their own tasks (they'll be more productive), and to help each other out (they'll work better as a team).
So start by letting them choose a couple of higher priority items from your list; things that they want to do, make it clear to them how the tasks relate to others' work, and encourage them to communicate while they work on things that depend on each others' work. (Avoid plaguing their work schedule with group meetings: they'll be just fine discussing things around a coffee or at each others' desks when needed.)
A point to keep in mind while doing so is to worry about the shier members in your team; they might be interested to work on this or that task but shy out of it because someone else with a bigger mouth wants to take care of it. Identify them quickly and force the odds a bit by periodically letting them choose their tasks first.
Your team will likewise include a few members who need to be assigned tasks. For these, proceed a bit like with the shy members (they'll frequently be the same ones, in my experience). The trick here is to know that, while most people dread making decisions out of the blue, they'll usually like to be faced with picking one option among a number of choices. what differs from a person to the next is the threshold. For some it's multitudes of options; for others it's as little as a single one. So, try to work out a number they're comfortable with. Then, in a first step, ask which among this, this and that task they'd rather do; and in a second, whether there is another task you hadn't thought of which they'd like even more. This will inhibit their fright and get them to choose their tasks without realizing it.
Another point to keep in mind is that you need to occasionally be firm. At the end of the day, you're the boss and if nobody is volunteering for a task in particular, you'll need to assign it outright. There are of course polite ways to do it, which I'm sure you know by now.
By the same token, be flexible. Some tasks will never seem to get done, because whoever volunteered quickly finds it boring or hard or whatever, and starts focusing on something else. Monitor for this and (gently) remove these tasks from them if needed. Your team members will appreciate if it comes from you reassigning their tasks, rather than them loosing their face in public ("sorry, I couldn't make it").