[만쥬네 동아리 가게] ToDoList (1) : MVVM

shstl98·2022년 2월 28일
0

Swift 어플 개발

목록 보기
1/2
post-thumbnail

Model

[Category]

구성

내용변수명Type
카테고리명nameString
카테고리 이미지imageImage

Source Code

import Foundation
import SwiftUI

struct Category: Identifiable {
    
    let name: String
    let image: Image
    
    var id: String {
        name
    }
}

[Society]

구성

내용변수명TypeOptional
동아리명nameString
카테고리categoryCategory
부서departmentString
주제themeString
주소addressString
대표 이미지mainImageImage
상세 이미지subImageImageOptional
인스타그램 주소instagramStringOptional
공고링크postStringOptional

Source Code

import Foundation
import SwiftUI

struct Society: Identifiable{
    let name: String
    let category: Category
    let department: String
    let theme: String
    let address: String
    let mainImage: Image
    let subImage: Image?
    let instagram: String?
    let post: String?
    
    var id: String{
        name + department
    }
}

DataSet

Category Data

구성

  • 스포츠
  • 취미
  • 봉사
  • 학술
  • 음악
  • 기타

Source Code

import Foundation
import SwiftUI

class CategoryData {
    
    static let Hobby = Category(name: "취미", image: Image("ManjuHobby"))
    static let Sports = Category(name: "스포츠", image: Image("ManjuSports"))
    static let Study = Category(name: "학술", image: Image("ManjuStudy"))
    static let Music = Category(name: "음악", image: Image("ManjuMusic"))
    static let Volunteer = Category(name: "봉사", image: Image("ManjuVolunteer"))
    static let Etc = Category(name: "기타", image: Image("ManjuFace"))

    static let Categories: [Category] = [
        
        CategoryData.Hobby,
        CategoryData.Sports,
        CategoryData.Study,
        CategoryData.Music,
        CategoryData.Volunteer,
        CategoryData.Etc,
        
    ]   
}

Sociey Data

구성

  • 스포츠 동아리 3개
  • 음악 동아리 3개

동아리에 맞는 이미지 다운로드 필요

Source Code

import SwiftUI

class SocietyData {
    
    static let Societies: [Society] = [
    
    Society(
        name: "Aqui",
        category: CategoryData.Hobby,
        department: "레저무예분과",
        theme: "락 밴드",
        address: "제 1학생회관 308호",
        mainImage: Image("Aqui"),
        subImage: nil,
        instagram: "ku._.youthhostel",
        post: "https://everytime.kr/418770/v/234934596"),
    
    Society(
        name: "Muse",
        category: CategoryData.Hobby,
        department: "레저무예분과",
        theme: "밴드",
        address: "제2학생회관 110호",
        mainImage: Image("Muse"),
        subImage: nil,
        instagram: "ku_mokbang",
        post: nil),
    
    Society(
        name: "WannaFamily",
        category: CategoryData.Hobby,
        department: "창작비평분과",
        theme: "힙합",
        address: "제2학생회관 207호",
        mainImage: Image("WannaFamily"),
        subImage: nil,
        instagram: "jiho3541",
        post: "https://everytime.kr/418770/v/235321252"),
    
    Society(
        name: "건국대 스키부",
        category: CategoryData.Sports,
        department: "레저무예분과",
        theme: "스키",
        address: "제 2학생회관 B133호",
        mainImage: Image("건국대 스키부"),
        subImage: nil,
        instagram: "ku_takku",
        post: "https://everytime.kr/418770/v/230535305"),
    
    Society(
        name: "초크",
        category: CategoryData.Sports,
        department: "레저무예분과",
        theme: "주짓수",
        address: "제2학생회관 109호",
        mainImage: Image("초크"),
        subImage: nil,
        instagram: nil,
        post: "https://everytime.kr/418770/v/235535322"),
    
    Society(
        name: "KTC",
        category: CategoryData.Sports,
        department: "레저무예분과",
        theme: "배드민턴",
        address: "제 1학생회관 403-2호",
        mainImage: Image("KTC"),
        subImage: nil,
        instagram: "ku_snowflower",
        post: "https://everytime.kr/418770/v/233968018")
    ]
    
}

ViewModel

MainViewModel

Source Code

import Foundation
import SwiftUI


class MainViewModel: ObservableObject{
    
    @Published var societies: [Society]
    @Published var categories: [Category]
    
    init(){
        self.societies = SocietyData.Societies
        self.categories = CategoryData.Categories
    }
}

View

참고 이미지

VIBE - 네이버 음악 스트리밍 어플


SoundCloud - 음악 스트리밍 어플

디자인 스케치

복습

View

HomeView

Source Code

import SwiftUI

struct HomeView: View {
    @Environment(\.colorScheme) var colorScheme
    let tabBarColor = Color("TabBarColor")

    var body: some View {
        TabView {
            ZStack {
                Color.accentColor.ignoresSafeArea()
                SelectView()
            }
            .tabItem {
                Image(systemName: "house.fill")
            }
            .navigationBarHidden(true).navigationBarTitle("")
            
            Text("Hello")
                .tabItem {
                    Image(systemName: "magnifyingglass")
                }
                .navigationBarHidden(true).navigationBarTitle("")

            
            Text("Hello")
                .tabItem {
                    Image(systemName: "person.fill")
                }
                .navigationBarHidden(true).navigationBarTitle("")

        }
        .onAppear() {
            UITabBar.appearance().isTranslucent = false
            UITabBar.appearance().backgroundColor = .init(tabBarColor)
        }
    }
}

Preview

SelectView

Source Code

import SwiftUI

struct SelectView: View {
    
    @EnvironmentObject private var mainViewModel: MainViewModel
    
    var body: some View {
        ScrollView(showsIndicators: false) {
            VStack(alignment: .leading, spacing: 45.0) {
                Text("만쥬네 동아리 메뉴")
                    .font(.title)
                    .fontWeight(.semibold)
                    .padding(.leading, 15.0)
                
                CategoryRowView()
                
                ForEach(mainViewModel.categories) { category in
                    SocietyRowView(group: category)
                }
            }
            .padding(.top, 30)
        }
    }
}

Preview

CategoryRowView

Source Code

import SwiftUI

struct CategoryRowView: View {
    
    @EnvironmentObject private var mainViewModel: MainViewModel
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        VStack(alignment: .leading, spacing: 20.0) {
            
            title
            
            ScrollView(.horizontal, showsIndicators: false){
                HStack(spacing: 10){
                    firstItem
                    restItem
                }
                .padding(.trailing, 15.0)
            }
        }
    }
}

extension CategoryRowView{
    
    private var title: some View{
        HStack{
            Text("전체 카테고리")
                .fontWeight(.bold)
                .padding(.leading, 15.0)
            
            Spacer()
            
            Text("더보기")
                .font(.subheadline)
                .tint(.secondary)
                .padding(.trailing, 15.0)
        }
    }
    
    private var firstItem: some View{
        VStack(alignment: .leading, spacing: 10){
            Image("ManjuStore")
                .resizable()
                .scaledToFit()
                .padding(5)
                .frame(width: 170, height: 170)
                .background(Color.white.opacity(colorScheme == .light ? 0.2 : 0.05))
                .cornerRadius(5)
            
            Text("전체 보기")
                .font(.subheadline)
                .tint(.primary)
                .padding(.leading, 3.0)
        }
        .padding(.leading, 15.0)
    }
    
    private var restItem: some View{
        
        ForEach(mainViewModel.categories) { category in
            VStack(alignment: .leading, spacing: 10){
                category.image
                    .resizable()
                    .scaledToFit()
                    .padding(5)
                    .frame(width: 170, height: 170)
                    .background(Color.white.opacity(colorScheme == .light ? 0.2 : 0.05))
                    .cornerRadius(5)
                
                Text(category.name)
                    .font(.subheadline)
                    .tint(.primary)
                    .padding(.leading, 3.0)
            }
        }
    }
}

Preview

SocietyRowView

Source Code

import SwiftUI

struct SocietyRowView: View {
    
    @EnvironmentObject private var mainViewModel: MainViewModel
    
    let group: Category

    var body: some View {
        VStack(alignment: .leading, spacing: 20.0) {
            
            title
            
            ScrollView(.horizontal, showsIndicators: false){
                HStack(spacing: -5){
                    itemList
                }
                .padding(.trailing, 15.0)

            }
        }
    }
}

extension SocietyRowView{
    private var title: some View{
        HStack{
            Text(group.name)
                .fontWeight(.bold)
                .padding(.leading, 15.0)

            Spacer()
            
            Text("더보기")
                .font(.subheadline)
                .tint(.secondary)
                .padding(.trailing, 15.0)
        }
    }
    
    private var itemList: some View{
        ForEach(mainViewModel.societies) { society in
            if society.category.name == group.name {
                VStack(alignment: .leading, spacing: 10){
                    society.mainImage
                        .resizable()
                        .scaledToFill()
                        .frame(width: 170, height: 170)
                        .cornerRadius(5)
                    
                    Text(society.name)
                        .font(.subheadline)
                        .tint(.primary)
                        .padding(.leading, 3.0)
                    
                    Text("\(society.theme) 동아리")
                        .font(.caption)
                        .foregroundColor(Color.secondary)
                        .padding(.leading, 3.0)

                }
                .padding(.leading, 15.0)
            }
        }
    }
}

Preview

최종

profile
허쓸하는 좀비

0개의 댓글