본문 바로가기
Projects/Swift

Swift :: 버스시간표 앱을 만들기 - 1 [ 버튼클릭 화면전환 ]

by 앱병찬 2024. 11. 28.

음 첫 개발공부로 무슨 어플이 좋을까 생각해보다가 

부산대(밀캠) - 밀양역 버스 시간표 어플을 만들어보기로 했다 ! (부산대 밀양캠퍼스 재학중)

 

참고할 사이트로는 

부산대학교 밀양캠퍼스 버스 시간표

https://pusan-university-miryangcampus.netlify.app/

를 참고할 것이다 !

 


 

 

1. 앱을 생성해주면 자동으로 ContentView가 생성된다.

#Preview 는 앱을 실행시키지 않아도 앱화면을 미리볼 수 있다. 나중에 필요없어지면 지울거 ㅎㅎ


 

2. 밀양역 방면과 부산대 방면 추가

밀양역 방면 - 부산대 -> 밀양역 / 부산대 방면 밀양역 -> 부산대 (잘못 씀)

  • VStack - 수직으로 뷰를 정렬해주는 컨테이너
  • Text - 텍스트 문자( 다른 페이지로 넘어가는 버튼으로 만들어 줄 것이다.)
    .multilineTextAlignment(.center) - 텍스트 중앙 정렬  

 

3. 텍스트에 화면 간 이동 기능 넣기, 텍스트 꾸미기
NavigationView, NavigationLink

  • NavigationView - 화면 간 이동을 가능하게 하는 컨테이너
  • NavigationLink - 사용자가 클릭하면 새로운 뷰로 이동할 수 있다.
    밀양역 방면의 텍스트를 클릭하면 MYS_Dir()로 이동하고
    부산대 방면의 텍스트를 클릭하면 PNU_Dir()로 이동한다.
  • spacing - 뷰 간의 거리 조절
  • Text를 꾸며줬다

 

4. 밀양역 방면 뷰(페이지) 데이터 넣고 리스트 만들어주기
부산대 방면도 데이터만 바꿔주면 된다!

MYS_Dir 전체 코드

 let timetable = [
            ["버스 노선", "부산대", "밀양역"],
            ["7번", "07:02", "07:18"],
            ["2번", "07:20", "7:32"],
            ["2번", "07:37", "7:56"],
            ["2번", "8:40", "8:52"],
            ["1번", "8:53", "9:12"],
            ["7번", "09:04", "09:20"],
            ["아리랑", "09:20", "09:26"],
            ["1번", "09:43", "10:00"],
            ["2번", "09:56", "10:12"]
        ]
  • 시간표 데이터를 행 단위로 정의한 2차원 배열
  • 첫 번째 행(["버스 노선", "부산대", "밀양역"])은 헤더로 사용
  • 이 데이터 구조는 LazyVGrid 와 ForEach 를 사용하여 동적으로 렌더링된다.
let columns = Array(repeating: GridItem(.flexible()), count: 3)
  • Array(repeating: element, count: n)
    주어진 요소 element 를 n번 반복하여 배열 생성하라
  • GridItem - LazyVGrid 와 LazyHGrid에서 각 열/행의 레이아웃 정의
    -> 각 열의 크기를 어떻게 계산할지 지정
    .flexible() - 열의 너비를 유동적으로 설정
    -> ex) 3개의 열, flexible() => 화면 너비를 3등분하여 각 열에 할당
    -> GridItem(.flexible(minumum: 50,maximum: 200) 으로 최대/최소 크기 지정가능

    .adaptive(fixed(100) - 열의 너비를 고정된 값(100)으로 설정
    .adaptive(minimum: 100) - 주어진 최소 크기(100)을 만족하며, 가능한 많은 열 생성

LazyVGrid(columns: columns, spacing: 20)

ForEach(0..<timetable.count, id: \.self) { rowIndex in

let itemId = "\(rowIndex)-\(columnIndex)"
Text(timetable[rowIndex][columnIndex])


< UI 구성 >

  1. 상단 제목: "부산대 -> 밀양역"
    Text를 사용해서 꾸며줌

  2. 시간표 레이아웃

    LazyVGrid(columns: columns, spacing: 20)
    LazyVGrid:
    그리드 레이아웃으로 시간표를 표시
    -> columns: 3열로 구성된 레이아웃 정의
    -> spacing: 20은 각 셀 간격을 설정

    ForEach(0..<timetable.count, id: \.self) { rowIndex in
    ForEach: 주어진 범위나 데이터 각 항목을 순회하면서 뷰 렌더링 함.
    -> ForEach( 컬렉션 or 범위, id: \.식별자)
    -> 0..< timetable.count - 범위 (시작:0, 종료점 timetable.count)
    -> { rowIndex in ... } - rowIndex 라는 이름으로 범위의 각 값을 받아, 해당 값을 기반으로 UI 구성

    timetable.count - 배열의 행 개수
    timetable[rowIndex].count - 그 행에 포함된 열의 개수

    id: \.self - 현재 요소 자체를 고유 식별자로 사용

  3. 셀 구성
    Text(timetable[rowIndex][columnIndex])
    현재 행과 열의 데이터를 텍스트로 표시

    let itemId = "\(rowIndex)-\(columnIndex)"
    문자열 보간법
    -> 문자열 안에 \ (변수) or \(표현식)을 삽입해 해당 값을 문자열에 포함시킨다.
    " - " : rowIndex와 columnIndex를 구분하기 위해 사용된 단순 구분자

    만약 itemId를 지정해주지 않으면 그 셀의 값 자체가 id가 되어버리므로 ex) id: "7번"
    동일한 값이 있으면 구분하지 못한다.

    결론: 행의 인덱스 값과 열의 인덱스값을 가져와 itemId로 만들어줬다.

 ⭐ 완 성 ⭐

 

아직 데이터를 맨위의 헤더 제외 9개만 넣어서 데이터가 별로없지만 다음시간에는 
시간표 데이터를 모두 넣고 디자인도 해 줄 것이다~!!

헷갈리거나 모르는거 있으면 댓글 적어주세요! (틀린것도 알려주세요 ㅠ)