iOS 27 introduces new SwiftUI drag and drop APIs including reorderable, reorderContainer, dragContainer, and configuration modifiers that enable reordering within and across collections, multi-item drag, and fine-grained control over how data is transferred during drag and drop operations.
• The new reorderable/reorderContainer API provides a declarative, no-boilerplate way to add cross-collection reordering without managing UICollectionView or complex gesture recognizers
• dragContainer enables true multi-item drag (e.g. stacked cards, batch file moves) with customizable preview formations like .stack or .list
• dropConfiguration and dragConfiguration give developers final-say control over whether data is copied or moved, and allow game-rule or business-logic validation at drop time
Demonstrates the new reorderable and reorderContainer modifiers to reorder cards across multiple piles, plus dragContainer for lifting a stack of cards together.
import SwiftUI
import UniformTypeIdentifiers
// MARK: - Model
struct PlayingCard: Identifiable, Hashable, Transferable {
let id: UUID
let label: String
let color: Color
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .playingCard)
}
}
extension UTType {
static let playingCard = UTType(exportedAs: "com.example.playingcard")
}
extension PlayingCard: Codable {
enum CodingKeys: String, CodingKey { case id, label, color }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
id = try c.decode(UUID.self, forKey: .id)
label = try c.decode(String.self, forKey: .label)
color = .blue
}
func encode(to encoder: Encoder) throws {
var c = encoder.container(keyedBy: CodingKeys.self)
try c.encode(id, forKey: .id)
try c.encode(label, forKey: .label)
}
}
// MARK: - Pile View
struct PileView: View {
let pileID: Int
@Binding var cards: [PlayingCard]
var body: some View {
VStack(spacing: -40) {
ForEach(cards) { card in
RoundedRectangle(cornerRadius: 10)
.fill(card.color.opacity(0.85))
.frame(width: 80, height: 110)
.overlay(Text(card.label).bold().foregroundStyle(.white))
.shadow(radius: 3)
// Make each card individually reorderable within the container
.reorderable(id: card.id)
}
}
.frame(minHeight: 150, alignment: .top)
}
}
// MARK: - Game View
struct CardGameView: View {
@State private var pile1: [PlayingCard] = [
PlayingCard(id: UUID(), label: "A♠", color: .indigo),
PlayingCard(id: UUID(), label: "K♠", color: .indigo),
PlayingCard(id: UUID(), label: "Q♠", color: .indigo),
]
@State private var pile2: [PlayingCard] = [
PlayingCard(id: UUID(), label: "A♥", color: .red),
PlayingCard(id: UUID(), label: "K♥", color: .red),
]
var body: some View {
HStack(spacing: 24) {
PileView(pileID: 0, cards: $pile1)
PileView(pileID: 1, cards: $pile2)
}
.padding()
// Scope reordering across BOTH piles in one container
.reorderContainer(itemType: PlayingCard.self) { difference in
// Apply a cross-pile move: remove from source, insert at destination
var combined = pile1 + pile2
combined.applyChanges(difference)
pile1 = Array(combined.prefix(pile1.count + difference.insertions.count - difference.removals.count))
pile2 = Array(combined.dropFirst(pile1.count))
}
// Multi-card drag: lift a card plus all cards above it in pile1
.dragContainer(itemType: PlayingCard.self) { cardID in
guard let idx = pile1.firstIndex(where: { $0.id == cardID }) else { return [] }
return Array(pile1[idx...])
}
.dragPreviewsFormation(.stack)
.dropPreviewsFormation(.stack)
.background(Color.green.opacity(0.3))
.navigationTitle("Card Piles")
}
}
// MARK: - Entry Point
struct ContentView: View {
var body: some View {
NavigationStack {
CardGameView()
}
}
}Liquid Glass is Apple's new material and visual design language introduced in iOS 27, bringing translucent, refractive glass-like surfaces to system and custom UI elements. It replaces the frosted vibrancy aesthetic with a more dynamic, depth-aware material that responds to content beneath it.
PaperKit is Apple's full-featured canvas framework — previously internal-only — now publicly available in iOS/macOS/visionOS 27. It powers the drawing and markup experience in Notes, Preview, and Freeform, giving developers access to a complete pencil, shapes, images, and text canvas with a rich data model.
Xcode 27 introduces a fully customizable toolbar and theme system, untitled scratch projects, coding agent integration directly in the editor, and the new Device Hub for evaluating apps across simulators and physical devices side-by-side.
In-depth guide
SwiftUI & Liquid Glass in iOS 27 →• dragContainer and reorderContainer must share the same Transferable item type or they will not interoperate correctly • reorderContainer implicitly provides its own dragContainer and dropDestination — adding a custom dragContainer below it overrides only the drag side, not the drop side • dropConfiguration has final authority over copy vs move; setting dragConfiguration to .move alone is not sufficient — the destination must also agree • dragPreviewsFormation and dropPreviewsFormation are separate modifiers; forgetting to set dropPreviewsFormation causes the drag preview to revert to default over drop targets
No special hardware required; drag and drop must be supported on the target platform
iOS 27 enforces stricter adaptivity requirements for UIKit apps, making iPhone apps fully resizable in iPhone Mirroring and on iPad, while introducing new navigation bar minimization controls, sidebar opt-in for iPhone tab bars, and prominent tab customization.