Update(ComponentWithVariable): add several compoenent and changes so we can

choose an image from the gallery
pull/22/head
Johan LACHENAL 11 months ago
parent c56dc05f3a
commit 6fa62e8f54

@ -29,7 +29,9 @@
C24DAB5E2C061E3A00681CD0 /* Language.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB5D2C061E3A00681CD0 /* Language.swift */; }; C24DAB5E2C061E3A00681CD0 /* Language.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB5D2C061E3A00681CD0 /* Language.swift */; };
C24DAB622C062DBC00681CD0 /* ProfileEdit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */; }; C24DAB622C062DBC00681CD0 /* ProfileEdit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */; };
C25220EE2C00AC7E0026B71F /* GameParametersMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220ED2C00AC7E0026B71F /* GameParametersMenuView.swift */; }; C25220EE2C00AC7E0026B71F /* GameParametersMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220ED2C00AC7E0026B71F /* GameParametersMenuView.swift */; };
C25220F32C00AF490026B71F /* EditComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220F22C00AF490026B71F /* EditComponent.swift */; }; C25220F32C00AF490026B71F /* EditTextComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25220F22C00AF490026B71F /* EditTextComponent.swift */; };
C2F015042C09BC6B000F7221 /* KeyboardReadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F015032C09BC6B000F7221 /* KeyboardReadable.swift */; };
C2F015062C09C384000F7221 /* EditImageComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F015052C09C384000F7221 /* EditImageComponent.swift */; };
C2F394082C0462400070B4F6 /* PhotoButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */; }; C2F394082C0462400070B4F6 /* PhotoButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */; };
C2F3940B2C0463940070B4F6 /* ProfileComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */; }; C2F3940B2C0463940070B4F6 /* ProfileComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -77,7 +79,9 @@
C24DAB5D2C061E3A00681CD0 /* Language.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Language.swift; sourceTree = "<group>"; }; C24DAB5D2C061E3A00681CD0 /* Language.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Language.swift; sourceTree = "<group>"; };
C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEdit.swift; sourceTree = "<group>"; }; C24DAB612C062DBC00681CD0 /* ProfileEdit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEdit.swift; sourceTree = "<group>"; };
C25220ED2C00AC7E0026B71F /* GameParametersMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameParametersMenuView.swift; sourceTree = "<group>"; }; C25220ED2C00AC7E0026B71F /* GameParametersMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameParametersMenuView.swift; sourceTree = "<group>"; };
C25220F22C00AF490026B71F /* EditComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditComponent.swift; sourceTree = "<group>"; }; C25220F22C00AF490026B71F /* EditTextComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditTextComponent.swift; sourceTree = "<group>"; };
C2F015032C09BC6B000F7221 /* KeyboardReadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardReadable.swift; sourceTree = "<group>"; };
C2F015052C09C384000F7221 /* EditImageComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditImageComponent.swift; sourceTree = "<group>"; };
C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoButtonComponent.swift; sourceTree = "<group>"; }; C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoButtonComponent.swift; sourceTree = "<group>"; };
C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileComponent.swift; sourceTree = "<group>"; }; C2F3940A2C0463940070B4F6 /* ProfileComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileComponent.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -178,6 +182,7 @@
C205A2BC2BF373380097BD93 /* Views */ = { C205A2BC2BF373380097BD93 /* Views */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2F015022C09BC56000F7221 /* EventTriggers */,
C24DAB5A2C061DAA00681CD0 /* Enum */, C24DAB5A2C061DAA00681CD0 /* Enum */,
C25220F02C00AD7F0026B71F /* Components */, C25220F02C00AD7F0026B71F /* Components */,
C25220EC2C00AC530026B71F /* GameParametersMenu */, C25220EC2C00AC530026B71F /* GameParametersMenu */,
@ -254,12 +259,21 @@
C20310D52BFCB5FB0031657D /* PickerComponent.swift */, C20310D52BFCB5FB0031657D /* PickerComponent.swift */,
C20310D92BFCC8600031657D /* ToggleComponent.swift */, C20310D92BFCC8600031657D /* ToggleComponent.swift */,
C24659E82BF60FAA004E80D5 /* ButtonComponent.swift */, C24659E82BF60FAA004E80D5 /* ButtonComponent.swift */,
C25220F22C00AF490026B71F /* EditComponent.swift */, C25220F22C00AF490026B71F /* EditTextComponent.swift */,
C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */, C2F394072C0462400070B4F6 /* PhotoButtonComponent.swift */,
C2F015052C09C384000F7221 /* EditImageComponent.swift */,
); );
path = Controls; path = Controls;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2F015022C09BC56000F7221 /* EventTriggers */ = {
isa = PBXGroup;
children = (
C2F015032C09BC6B000F7221 /* KeyboardReadable.swift */,
);
path = EventTriggers;
sourceTree = "<group>";
};
C2F394092C04636C0070B4F6 /* Visuals */ = { C2F394092C04636C0070B4F6 /* Visuals */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -402,6 +416,7 @@
C205A2B92BF373360097BD93 /* ContentView.swift in Sources */, C205A2B92BF373360097BD93 /* ContentView.swift in Sources */,
82CE59EF2C0460E500ADEE24 /* SpriteMoople.swift in Sources */, 82CE59EF2C0460E500ADEE24 /* SpriteMoople.swift in Sources */,
82CE59E92C045D1100ADEE24 /* GameScene.swift in Sources */, 82CE59E92C045D1100ADEE24 /* GameScene.swift in Sources */,
C2F015062C09C384000F7221 /* EditImageComponent.swift in Sources */,
82F9D3312BFE3A9F009EDFAF /* HistoryGameDetail.swift in Sources */, 82F9D3312BFE3A9F009EDFAF /* HistoryGameDetail.swift in Sources */,
C24659E92BF60FAA004E80D5 /* ButtonComponent.swift in Sources */, C24659E92BF60FAA004E80D5 /* ButtonComponent.swift in Sources */,
C24DAB5E2C061E3A00681CD0 /* Language.swift in Sources */, C24DAB5E2C061E3A00681CD0 /* Language.swift in Sources */,
@ -410,9 +425,10 @@
82F9D3362BFE3B3C009EDFAF /* HistoryView.swift in Sources */, 82F9D3362BFE3B3C009EDFAF /* HistoryView.swift in Sources */,
C20310D82BFCC2410031657D /* GeneralParametersMenuView.swift in Sources */, C20310D82BFCC2410031657D /* GeneralParametersMenuView.swift in Sources */,
C2F3940B2C0463940070B4F6 /* ProfileComponent.swift in Sources */, C2F3940B2C0463940070B4F6 /* ProfileComponent.swift in Sources */,
C2F015042C09BC6B000F7221 /* KeyboardReadable.swift in Sources */,
C205A2B72BF373360097BD93 /* ArkitDoushiQiApp.swift in Sources */, C205A2B72BF373360097BD93 /* ArkitDoushiQiApp.swift in Sources */,
C24DAB5C2C061DC700681CD0 /* AI.swift in Sources */, C24DAB5C2C061DC700681CD0 /* AI.swift in Sources */,
C25220F32C00AF490026B71F /* EditComponent.swift in Sources */, C25220F32C00AF490026B71F /* EditTextComponent.swift in Sources */,
C20310D62BFCB5FB0031657D /* PickerComponent.swift in Sources */, C20310D62BFCB5FB0031657D /* PickerComponent.swift in Sources */,
82F9D3332BFE3B12009EDFAF /* HistoryHeader.swift in Sources */, 82F9D3332BFE3B12009EDFAF /* HistoryHeader.swift in Sources */,
82CE59EB2C045E3800ADEE24 /* GameView.swift in Sources */, 82CE59EB2C045E3800ADEE24 /* GameView.swift in Sources */,

@ -0,0 +1,74 @@
//
// EditImageComponent.swift
// ArkitDoushiQi
//
// Created by Johan LACHENAL on 31/05/2024.
//
import SwiftUI
import PhotosUI
struct EditImageComponent: View {
@State private var avatarItem: PhotosPickerItem?
@State private var avatarImage: Image?
let color: Color
let profileWidth: CGFloat
let profileHeight: CGFloat
let defaultImage: Image
let imageTextChange: String
var body: some View {
HStack {
VStack {
HStack {
GeometryReader { geometry in
ZStack {
// Background color
color
// Profile Image
ProfileComponent(color: color, profileWidth: profileWidth, profileHeight: profileHeight, image: avatarImage ?? defaultImage
)
}
// Ensure the ZStack takes the size of the GeometryReader
.frame(width: geometry.size.width, height: geometry.size.height)
.clipShape(Circle())
}
.aspectRatio(1, contentMode: .fit)
.frame(width: profileWidth, height: profileHeight) // Optional fixed size
PhotosPicker(selection: $avatarItem, matching: .images) {
Text(imageTextChange)
}
.onChange(of: avatarItem) { newValue in
if let newItem = newValue {
Task {
if let data = try? await newItem.loadTransferable(type: Data.self),
let uiImage = UIImage(data: data) {
avatarImage = Image(uiImage: uiImage)
} else {
print("Failed to load image")
}
}
}
}
}
}
}
}
}
struct EditImageComponent_Previews: PreviewProvider {
static var previews: some View {
EditImageComponent(
color: Color(.red),
profileWidth: 100,
profileHeight: 100,
defaultImage: Image("profil"),
imageTextChange: "Changer d'avatar"
)
.previewLayout(.sizeThatFits)
.padding()
}
}

@ -7,7 +7,7 @@
import SwiftUI import SwiftUI
struct EditComponent: View { struct EditTextComponent: View {
let explanation : String let explanation : String
@State private var name : String @State private var name : String
init(explanation: String, value: String) { init(explanation: String, value: String) {
@ -23,8 +23,8 @@ struct EditComponent: View {
} }
} }
struct EditComponent_Previews: PreviewProvider { struct EditTextComponent_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
EditComponent(explanation: "Nom du Joueur 1", value: "Joueur 1") EditTextComponent(explanation: "Nom du Joueur 1", value: "Joueur 1")
} }
} }

@ -8,10 +8,10 @@
import SwiftUI import SwiftUI
struct ProfileComponent: View { struct ProfileComponent: View {
let imageName: String
let color : Color let color : Color
let profileWidth : CGFloat let profileWidth : CGFloat
let profileHeight : CGFloat let profileHeight : CGFloat
let image : Image
var body: some View { var body: some View {
GeometryReader { geometry in GeometryReader { geometry in
ZStack { ZStack {
@ -19,7 +19,7 @@ struct ProfileComponent: View {
color color
// Profile Image // Profile Image
Image(imageName) image
.resizable() .resizable()
.scaledToFill() .scaledToFill()
.clipShape(Circle()) .clipShape(Circle())
@ -37,10 +37,10 @@ struct ProfileComponent: View {
struct ProfileComponent_Previews: PreviewProvider { struct ProfileComponent_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
ProfileComponent( ProfileComponent(
imageName: "profil",
color: Color(.red), color: Color(.red),
profileWidth: 200, profileWidth: 200,
profileHeight : 200 profileHeight : 200,
image: Image("profil")
) )
.previewLayout(.sizeThatFits) .previewLayout(.sizeThatFits)
.padding() .padding()

@ -8,20 +8,36 @@
import SwiftUI import SwiftUI
struct ProfileEdit: View { struct ProfileEdit: View {
let color : Color
let profileWidth : CGFloat
let profileHeight : CGFloat
let defaultImage: Image
let imageTextChange : String
var body: some View { var body: some View {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) VStack(alignment: .leading) {
} EditImageComponent(
} color: color,
profileWidth: profileWidth,
struct ProfileEdit_Previews: PreviewProvider { profileHeight: profileHeight,
static var previews: some View { defaultImage: defaultImage,
VStack { imageTextChange: imageTextChange
ProfileComponent(imageName: "profil", color: Color(.red), profileWidth: 100, profileHeight: 100) ).padding(EdgeInsets(top: 0, leading: 32, bottom: 0, trailing: 32))
VStack(alignment: .trailing) { VStack(alignment: .trailing) {
HStack { HStack {
EditComponent(explanation: "Nom du Joueur 1", value: "Joueur 1") EditTextComponent(explanation: "Nom du Joueur 1", value: "Joueur 1")
} }
} }
} }
} }
} }
struct ProfileEdit_Previews: PreviewProvider {
static var previews: some View {
ProfileEdit(color: Color(.red),
profileWidth: 100,
profileHeight: 100,
defaultImage: Image("profil"),
imageTextChange: "Changer d'avatar"
)
}
}

@ -0,0 +1,31 @@
//
// KeyboardReadable.swift
// ArkitDoushiQi
//
// Created by Johan LACHENAL on 31/05/2024.
//
import Foundation
import Combine
import UIKit
// Publisher to read keyboard changes.
protocol KeyboardReadable {
var keyboardPublisher: AnyPublisher<Bool, Never> { get }
}
extension KeyboardReadable {
var keyboardPublisher: AnyPublisher<Bool, Never> {
Publishers.Merge(
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { _ in true },
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in false }
)
.eraseToAnyPublisher()
}
}

@ -22,9 +22,10 @@ enum Rules: String, CaseIterable, Identifiable, Hashable {
var id: String { self.rawValue } var id: String { self.rawValue }
} }
struct GameParametersMenuView: View { struct GameParametersMenuView: View, KeyboardReadable {
@State private var selectedAIOption: AIT = .RandomAction @State private var selectedAIOption: AIT = .RandomAction
@State private var selectedRulesOption: Rules = .Regular @State private var selectedRulesOption: Rules = .Regular
@State private var isKeyboardVisible = false
var body: some View { var body: some View {
NavigationView { NavigationView {
VStack(alignment: .leading) { VStack(alignment: .leading) {
@ -37,24 +38,16 @@ struct GameParametersMenuView: View {
PickerComponent(title: "Sélectionne une IA :", PickerComponent(title: "Sélectionne une IA :",
selectedOption: $selectedAIOption, selectedOption: $selectedAIOption,
options: AIT.allCases) options: AIT.allCases)
ProfileComponent( ProfileEdit(color: Color(.red), profileWidth: 100, profileHeight: 100, defaultImage: Image("profil"), imageTextChange: "changer l'avatar du joueur 1")
imageName: "profil", ProfileEdit(color: Color(.blue), profileWidth: 100, profileHeight: 100, defaultImage: Image("profil"), imageTextChange: "changer l'avatar du joueur 2")
color: Color(.red), if !isKeyboardVisible
profileWidth: 100, {
profileHeight : 100 ButtonComponent(title: "Lancer la partie") {
) GameView()
EditComponent(explanation: "Nom du joueur 1", value: "Joueur 1").frame(width: .infinity,height: 100) }.padding(EdgeInsets(top: 10, leading: 32, bottom: 10, trailing: 32))
ProfileComponent( }
imageName: "profil",
color: Color(.red),
profileWidth: 100,
profileHeight : 100
)
EditComponent(explanation: "Nom du joueur 2",value: "Joueur 2").frame(width: .infinity,height: 100)
ButtonComponent(title: "Lancer la partie") {
GameView()
}.padding(EdgeInsets(top: 10, leading: 32, bottom: 10, trailing: 32))
} }
.onReceive(keyboardPublisher) { value in isKeyboardVisible = value }
.frame(maxHeight: .infinity, alignment: .top) .frame(maxHeight: .infinity, alignment: .top)
} }
} }

Loading…
Cancel
Save