할 일 목록 만들기

서희찬·2022년 3월 7일
0

swift

목록 보기
4/17
post-thumbnail

스토리보드 꾸미기

할 일 목록을 만들기 위해서는 기존의 컨트롤러가 아니라 테이블뷰컨트롤러가 있어야한다.
기존의 것들을 지우고 테이블 뷰컨트롤 추가하고 navigation controller를 추가해주자

을 체크해서 앱이 실행될 때 처음으로 가야 할 뷰 컨트롤러를 네비게이션 컨트롤러로 선택해주자


바 버튼 아이템을 추가하고 그 후 뷰 컨트롤러 2개를 추가해주고
세그웨이 show로 연결시켜준다. 아래 세그웨이에 identifier -> sgDetail로 해준다. 그리고 navigation Item 타이틀을 바꿔준다.
그리고 위와 같이 타이틀을 바꿔주고 필요 요소들을 넣어준다.

이제 swift파일을 작성해줘야한다
3개의 파일을 추가하자

  • AddViewController (Sub : UIView
  • TableViewController ( sub : UiTableView
  • DetailViewController ( sub : UIView
    로 3개의 파일을 추가한다.
    그러고 컨트롤러와 파일을 연결시켜주자

아웃렛 변수, 액션 함수 추가

아웃렛 변수

  • 테이블 뷰
  • add view -> 텍스트필드
  • detail view -> Label

액션 함수

  • Add view -> Add 버튼

테이블 목록 보여주기

앱이 실행됐을때 기본적으로 아이콘 포함된 3개의 목록이 나타나게 하자
그러므로 목록과 함께 아이콘으로 사용될 이미지 추가하고
목록보여주는 코드를 작성하자

TableViewController.swift
import UIKit

var items = ["책 구매","희찬와 약속","알고리즘 스터디 준비하기"]
var itemsImageFile = ["cart.png","clock.png","pencil.png"]

class TableViewController: UITableViewController {

    @IBOutlet var tvListView: UITableView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1 // 보통 테이블 안에 섹션 1개 이므로 리턴 1을 한다.
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return items.count //섹션당 열의 개수는 items의 개수이다.
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        cell.textLabel?.text = items[(indexPath as NSIndexPath).row] // 셀의 텍스트 레이블에 items대입
        cell.imageView?.image = UIImage(named: itemsImageFile[(indexPath as NSIndexPath).row]) // 이미지뷰에 사진 대입

        return cell
    }

이렇게 작성하고 실행해보면
이렇게 뜬다!!

목록 삭제하기

위의 파일에

    //삭제버튼 이름수정
    override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "삭제"
    }
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            items.remove(at: (indexPath as NSIndexPath).row)
            itemsImageFile.remove(at: (indexPath as NSIndexPath).row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }

이 코드를 추가하여 delete 버튼을 만드는데
"삭제"라고 만들기 위해 이름수정 함수를 하나 만들어줘서 적용시켜주면

위와 같이 짜라란~

바 버튼으로 목록 삭제하기

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
         self.navigationItem.leftBarButtonItem = self.editButtonItem // 왼쪽에 edit 버튼 만들기
    }

viewDidLoad 함수에 마지막줄 주석 풀어주고 right->left로 바꿔주면 Edit버튼을 눌러서 삭제도 가능하다.

목록 순서 바꾸기

목록 옮기는 함수안에
변수를 만들어서 이동할 변수를 기억한 후 이동할 목록을 삭제하고 변수에 저장된 내용을 이동한 곳에 삽입하는 코드를 작성하자

    // 목록 옮기기 함수
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        
        // 이동할 아이템의 위치 저장 변수
        let itemToMove = items[(fromIndexPath as NSIndexPath).row]
        let itemImageToMove = itemsImageFile[(fromIndexPath as NSIndexPath).row]
        
        // 이동할 아이템 삭제, 삭제한 아이템 뒤의 인덱스 재정렬 됨
        items.remove(at: (fromIndexPath as NSIndexPath).row)
        itemsImageFile.remove(at: (fromIndexPath as NSIndexPath).row)
        
        // 삭제된 아이템을 이동할 위치로 삽입, 삽입한 아이템 뒤의 아이템들의 인덱스 재정렬
        items.insert(itemToMove, at: (to as NSIndexPath).row)
        itemsImageFile.insert(itemImageToMove, at: (to as NSIndexPath).row)
    }

이렇게 목록을 옮길 수 있다.
이제 목록 추가하기를 해보자

새 목록 추가하기

이제 AddViewController로 와서 버튼 액션 함수를

    @IBAction func btnAddItem(_ sender: UIButton) {
        items.append(tfAddItem.text!) // items 텍스트 필드의 텍스트 값 추가
        itemsImageFile.append("clock.png")
        tfAddItem.text="" // 텍필 내용 삭제
        _ = navigationController?.popViewController(animated: true) //테이블 뷰로 돌아가게 한다! (팝)
        
    }

다음과 같이 작성해주면 화면 전환이 잘 일어나지만 데이터 전달은 아직 하지 못한다.
다시 TableViewController로 돌아와서

    // 뷰가 전환될 때 호출되는 함수, 리스트가 추가되어 Main View로 돌아올때 호출되며 추가된 내용을 리스트에 보여준다.
    override func viewWillAppear(_ animated: Bool) {
        tvListView.reloadData() // 추가된 목록을 불러들인다.
    }

이렇게 목록을 reload해서 추가된것을 보여주는 함수를 작성하고 실행해보면 정상적으로 추가되는것을 확인할 수 있다.

목록의 세부 내용 보기

우선, DetailViewController를 작성해주자

//
//  DetailViewController.swift
//  Table
//
//  Created by 서희찬 on 2022/03/08.
//

import UIKit

class DetailViewController: UIViewController {
    
    var receiveItem = "" // mainView에서 받을 텍스트를 위해 변수 receive Item선언 한다.

    @IBOutlet weak var lblItem: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // view가 노출될 때마다 이 내용을 레이블의 텍스트로 표시
        lblItem.text = receiveItem
        }
    
    // main View에서 변수를 받기 위한 함수 추가
    func receiveItem(_ item: String)
    {
        receiveItem = item
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

그 후 TableViewController.swift를 수정하자

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
        if segue.identifier == "sgDetail"{
            let cell = sender as! UITableViewCell
            let indexPath = self.tvListView.indexPath(for: cell)
            let detailView = segue.destination as! DetailViewController
            detailView.receiveItem(items[((indexPath! as NSIndexPath).row)])
        }


짜라란~
디테일 페이지까지 완성이다~

전체코드

TableViewController

//
//  TableViewController.swift
//  Table
//
//  Created by 서희찬 on 2022/03/08.
//

import UIKit

var items = ["책 구매","희찬와 약속","알고리즘 스터디 준비하기"]
var itemsImageFile = ["cart.png","clock.png","pencil.png"]

class TableViewController: UITableViewController {

    @IBOutlet var tvListView: UITableView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
         self.navigationItem.leftBarButtonItem = self.editButtonItem // 왼쪽에 edit 버튼 만들기
    }
    
    // 뷰가 전환될 때 호출되는 함수, 리스트가 추가되어 Main View로 돌아올때 호출되며 추가된 내용을 리스트에 보여준다.
    override func viewWillAppear(_ animated: Bool) {
        tvListView.reloadData() // 추가된 목록을 불러들인다.
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1 // 보통 테이블 안에 섹션 1개 이므로 리턴 1을 한다.
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return items.count //섹션당 열의 개수는 items의 개수이다.
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        cell.textLabel?.text = items[(indexPath as NSIndexPath).row] // 셀의 텍스트 레이블에 items대입
        cell.imageView?.image = UIImage(named: itemsImageFile[(indexPath as NSIndexPath).row]) // 이미지뷰에 사진 대입

        return cell
    }

    /*
    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */

    
    //삭제버튼 이름수정
    override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "삭제"
    }
    
    //삭제 구현 함수
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            items.remove(at: (indexPath as NSIndexPath).row)
            itemsImageFile.remove(at: (indexPath as NSIndexPath).row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }


    // 목록 옮기기 함수
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        
        // 이동할 아이템의 위치 저장 변수
        let itemToMove = items[(fromIndexPath as NSIndexPath).row]
        let itemImageToMove = itemsImageFile[(fromIndexPath as NSIndexPath).row]
        
        // 이동할 아이템 삭제, 삭제한 아이템 뒤의 인덱스 재정렬 됨
        items.remove(at: (fromIndexPath as NSIndexPath).row)
        itemsImageFile.remove(at: (fromIndexPath as NSIndexPath).row)
        
        // 삭제된 아이템을 이동할 위치로 삽입, 삽입한 아이템 뒤의 아이템들의 인덱스 재정렬
        items.insert(itemToMove, at: (to as NSIndexPath).row)
        itemsImageFile.insert(itemImageToMove, at: (to as NSIndexPath).row)
    }
    

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */

    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "sgDetail"{
                let cell = sender as! UITableViewCell
                let indexPath = self.tvListView.indexPath(for: cell)
                let detailView = segue.destination as! DetailViewController
                detailView.receiveItems(items[((indexPath! as NSIndexPath).row)])
            }
    }
}

AddViewController

//
//  AddViewController.swift
//  Table
//
//  Created by 서희찬 on 2022/03/08.
//

import UIKit

class AddViewController: UIViewController {

    @IBOutlet weak var tfAddItem: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    @IBAction func btnAddItem(_ sender: UIButton) {
        items.append(tfAddItem.text!) // items 텍스트 필드의 텍스트 값 추가
        itemsImageFile.append("clock.png")
        tfAddItem.text="" // 텍필 내용 삭제
        _ = navigationController?.popViewController(animated: true) //테이블 뷰로 돌아가게 한다! (팝)
        
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

DetailViewController

//
//  DetailViewController.swift
//  Table
//
//  Created by 서희찬 on 2022/03/08.
//

import UIKit

class DetailViewController: UIViewController {
    
    var receiveItem = "ㅋㅋ" // mainView에서 받을 텍스트를 위해 변수 receive Item선언 한다.

    @IBOutlet weak var lblItem: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // view가 노출될 때마다 이 내용을 레이블의 텍스트로 표시
        lblItem.text = receiveItem
        }
    
    // main View에서 변수를 받기 위한 함수 추가
    func receiveItems(_ item: String)
    {
        receiveItem = item
    }
    

    // MARK: - Navigation
//
//    // In a storyboard-based application, you will often want to do a little preparation before navigation
//    // 세그웨이를 이용하여 뷰를 이동하는 함수
//    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//        // Get the new view controller using segue.destination.
//        // Pass the selected object to the new view controller.
//        if segue.identifier == "sgDetail"{
//            let cell = sender as! UITableViewCell
//            let indexPath = self.tvListView.indexPath(for: cell)
//            let detailView = segue.destination as! DetailViewController
//            detailView.receiveItem(items[((i))])
//        }
//    }
}

흐하~!

profile
부족한 실력을 엉덩이 힘으로 채워나가는 개발자 서희찬입니다 :)

0개의 댓글