From 32ea11b52596bd7c3e9d59bc80d849c54c63e788 Mon Sep 17 00:00:00 2001 From: Ching Date: Wed, 15 Feb 2023 17:34:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(view):=20=E5=A2=9E=E5=8A=A0=20aspectvgrid?= =?UTF-8?q?=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 aspectvgrid view Signed-off-by: Ching --- Memorize.xcodeproj/project.pbxproj | 4 +++ Memorize/AspectVGrid.swift | 48 ++++++++++++++++++++++++++++++ Memorize/EmojiMemoryGameView.swift | 29 ++++++++++-------- 3 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 Memorize/AspectVGrid.swift diff --git a/Memorize.xcodeproj/project.pbxproj b/Memorize.xcodeproj/project.pbxproj index ad020ae..a342639 100644 --- a/Memorize.xcodeproj/project.pbxproj +++ b/Memorize.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 245099F32998EAD6000CE9DA /* MemoryGame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 245099F22998EAD6000CE9DA /* MemoryGame.swift */; }; 245099F52998EC71000CE9DA /* EmojiMemoryGame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 245099F42998EC71000CE9DA /* EmojiMemoryGame.swift */; }; 24E748FC29993782009B5FE8 /* Constans.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E748FB29993781009B5FE8 /* Constans.swift */; }; + 24E748FE299944F4009B5FE8 /* AspectVGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E748FD299944F4009B5FE8 /* AspectVGrid.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -25,6 +26,7 @@ 245099F22998EAD6000CE9DA /* MemoryGame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryGame.swift; sourceTree = ""; }; 245099F42998EC71000CE9DA /* EmojiMemoryGame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMemoryGame.swift; sourceTree = ""; }; 24E748FB29993781009B5FE8 /* Constans.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constans.swift; sourceTree = ""; }; + 24E748FD299944F4009B5FE8 /* AspectVGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AspectVGrid.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -59,6 +61,7 @@ children = ( 240EDC3E2998A3B900A46AC9 /* MemorizeApp.swift */, 240EDC402998A3B900A46AC9 /* EmojiMemoryGameView.swift */, + 24E748FD299944F4009B5FE8 /* AspectVGrid.swift */, 24E748FB29993781009B5FE8 /* Constans.swift */, 245099F22998EAD6000CE9DA /* MemoryGame.swift */, 245099F42998EC71000CE9DA /* EmojiMemoryGame.swift */, @@ -148,6 +151,7 @@ files = ( 245099F32998EAD6000CE9DA /* MemoryGame.swift in Sources */, 240EDC412998A3B900A46AC9 /* EmojiMemoryGameView.swift in Sources */, + 24E748FE299944F4009B5FE8 /* AspectVGrid.swift in Sources */, 24E748FC29993782009B5FE8 /* Constans.swift in Sources */, 240EDC3F2998A3B900A46AC9 /* MemorizeApp.swift in Sources */, 245099F52998EC71000CE9DA /* EmojiMemoryGame.swift in Sources */, diff --git a/Memorize/AspectVGrid.swift b/Memorize/AspectVGrid.swift new file mode 100644 index 0000000..e923210 --- /dev/null +++ b/Memorize/AspectVGrid.swift @@ -0,0 +1,48 @@ +// +// AspectVGrid.swift +// Memorize +// +// Created by ching on 2023/2/13. +// + +import SwiftUI + +struct AspectVGrid: View where ItemView: View, Item: Identifiable { + var items: [Item] + var aspectRatio: CGFloat + var content: (Item) -> ItemView + var body: some View { + let width: CGFloat = 100 + LazyVGrid(columns: [GridItem(.adaptive(minimum: width))]) { + ForEach(items) { + item in content(item).aspectRatio(aspectRatio, contentMode: .fit) + } + } + } + + private func widthThatFits(itemCount: Int, in size: CGSize, itemAspectRatio: CGFloat) -> CGFloat { + var columCount = 1 + var rowCount = itemCount + + repeat { + let itemWidth = size.width / CGFloat(columCount) + let itemHeight = itemWidth / itemAspectRatio + if CGFloat(rowCount) * itemHeight < size.height { + break + } + columCount += 1 + rowCount = (itemCount + columCount - 1) / columCount + } while columCount < itemCount + + if columCount > itemCount { + columCount = itemCount + } + return floor(size.width / CGFloat(columCount)) + } +} + +// struct AspectVGrid_Previews: PreviewProvider { +// static var previews: some View { +// AspectVGrid() +// } +// } diff --git a/Memorize/EmojiMemoryGameView.swift b/Memorize/EmojiMemoryGameView.swift index 990d3de..485f73d 100644 --- a/Memorize/EmojiMemoryGameView.swift +++ b/Memorize/EmojiMemoryGameView.swift @@ -10,20 +10,25 @@ import SwiftUI struct EmojiMemoryGameView: View { @ObservedObject var game: EmojiMemoryGame var body: some View { - ScrollView { - LazyVGrid(columns: [GridItem(.adaptive(minimum: const.DrawingConstants.gridWidth))]) { - ForEach(game.cards) { - card in CardView(card: card).aspectRatio(const.DrawingConstants.gridAspectRatio, contentMode: .fit) - .onTapGesture { - game.choose(card) - } +// ScrollView { +// LazyVGrid(columns: [GridItem(.adaptive(minimum: const.DrawingConstants.gridWidth))]) { +// ForEach(game.cards) { +// card in CardView(card: card).aspectRatio(const.DrawingConstants.gridAspectRatio, contentMode: .fit) +// .onTapGesture { +// game.choose(card) +// } +// } +// } +// } +// .foregroundColor(/*@START_MENU_TOKEN@*/ .red/*@END_MENU_TOKEN@*/) +// .padding(.horizontal) + AspectVGrid(items: game.cards, aspectRatio: const.DrawingConstants.gridAspectRatio, content: { + card in CardView(card: card).aspectRatio(const.DrawingConstants.gridAspectRatio, contentMode: .fit) + .onTapGesture { + game.choose(card) } - } - } - .foregroundColor(/*@START_MENU_TOKEN@*/ .red/*@END_MENU_TOKEN@*/) - .padding(.horizontal) + }) } -} struct CardView: View { let card: EmojiMemoryGame.Card