[Swift] 'Test UIKit' 프로젝트(2)

Erick·2023년 2월 4일
0
post-thumbnail

'Test UIKit' 프로젝트(2)


앱의 구현

Controller

Controller는 사용자가 컨트롤하는 부분을 코드로 짠 부분입니다.
하지만 Swift에선 ViewController를 사용하기 때문에 어쩔 수 없이 View와 Controller를 완벽하게 분리할 수 없습니다.

//DetailViewController.swift 
private var detailView = DetailView()
    
override func loadView() {
        
    self.view = detailView
} 

최대한 View와 Controller를 분리하기 위해 만들어둔 DetailView를 ViewController의 View를 불러올 때 self.view에 넣는 방식으로 구현하여 View와 Controller를 분리하였습니다.

TableViewCell

Controller에서 중요한 부분이 바로 TableView였습니다.

위와 같이 TableView 위에 사용자가 코드를 수정하거나 선택할 수 있도록 하는 컨트롤러를 올려야 하기 때문에 Code를 입력할 수 있는 CodeTableViewCell과 ButtonTableViewCell을 따로 만들어야 했습니다.

//테이블뷰 셀 설정하는 함수
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //CodeTableViewCell 설정
        if indexPath.row <= (uikitCodeData?.UIKitFunction.count)! - 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CodeCell", for: indexPath) as! DetailCodeTableViewCell
            
            cell.label.text = uikitCodeData?.UIKitFunction[indexPath.row]
            cell.textField.placeholder = uikitCodeData?.UIKitFunctionType[indexPath.row]
            cell.textField.tag = indexPath.row
            cell.textField.delegate = self
            
            return cell
            //ButtonTableViewCell 설정
        } else if indexPath.row >= (uikitCodeData?.UIKitFunction.count)! {
            let bCell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as! DetailButtonTableViewCell
            bCell.label.text = uikitButtonData?.UIKitFunction[indexPath.row - (uikitCodeData?.UIKitFunction.count)!]
            bCell.button.setTitle(uikitButtonData?.UIKitFunctionType[indexPath.row - (uikitCodeData?.UIKitFunction.count)!], for: .normal)
            
            return bCell
        }
    }

셀의 indexPath.row 사용하여 codeFunction의 개수를 기준으로 CodeCell과 ButtonCell을 나누었습니다.

CodeCell

CodeCell에는 TextField에 tag를 만들어 엔터를 눌렀을 때 tag 번호와 Data를 이용해 UIKit이 바뀌도록 설정하였습니다.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true)
    codeTag = textField.tag
    textData = textField.text!
        
    setupCode()
        
    return true
}
//Data를 적용하는 함수
func setupCode() {
    switch codeTag {
    case 0:
        detailView.label.text = textData
    case 1:
        guard let value = Int(textData) else { return }
        detailView.label.numberOfLines = value
    default:
        break
    }
}

위 코드는 LabelDetailViewController에서 엔터를 눌렀을 때 받아온 Data를 사용해 label의 text와 numberOfLines이 바뀌도록 설정한 코드입니다.
TextField의 tag를 통해 각 셀의 TextField를 구별합니다.

ButtonCell

ButtonCell은 사용자가 알기 힘든 Style이나 UIColor 등을 Button에 메뉴를 추가하여 구현하였습니다.

Function의 이름으로 각 셀을 구별하여 메뉴를 만들고 button에 추가하는 방식으로 구현했습니다.

switch uikitButtonData?.UIKitFunction[indexPath.row] {
    //label.font Function의 버튼 설정
    case "label.font":
        let systemFont = UIAction(title: "systemFont", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.font = .systemFont(ofSize: 18) })
        let boldSystemFont = UIAction(title: "boldSystemFont", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.font = .boldSystemFont(ofSize: 18) })
        bCell.button.menu = UIMenu(title: "UIFont",
                                     image: UIImage(systemName: ""),
                                     identifier: nil,
                                     options: .displayInline,
                                   children: [systemFont, boldSystemFont])
    //label.textColor Function의 버튼 설정
    case "label.textColor":
        let red = UIAction(title: "red", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.textColor = .red })
        let green = UIAction(title: "green", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.textColor = .green })
        let blue = UIAction(title: "blue", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.textColor = .blue })
        let gray = UIAction(title: "gray", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.textColor = .gray })
        let white = UIAction(title: "white", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.textColor = .white })
        let black = UIAction(title: "black", image: UIImage(systemName: ""), handler: { _ in self.detailView.label.textColor = .black})
        bCell.button.menu = UIMenu(title: "UIColor",
                                     image: UIImage(systemName: ""),
                                     identifier: nil,
                                     options: .displayInline,
                                     children: [red, green, blue, gray, white, black])
    default:
        break
    }

Function에 맞는 UIAction을 만들고 Button의 menu에 추가하면 Button을 눌렀을 때 나오는 메뉴를 만들 수 있습니다.

그리고 ButtonTableViewCell에서 button을 생성할 때 .showsMenuAsPrimaryAction을 true로 설정해야 눌렀을 때 바로 메뉴가 나오도록 생성할 수 있습니다.

'Test UIKit' 실행

Test UIKit이 실행되는 모습입니다.


마치며

이번 프로젝트는 처음 기획하며 생각했던 것보다 많이 배우게 된 프로젝트였네요.
코드로만 UI를 구현하며 스토리보드 없이 UI를 짜는 것에 익숙해졌고, MVC패턴을 사용하여 코드를 Model, View, Controller를 기준으로 나누면 코드의 가독성 좋아지고, 새로운 코드를 짜거나 보수하는데 용이하다는 것을 느꼈습니다.
프로젝트를 진행하며 새롭게 하고 싶은 프로젝트가 2개 정도 떠올라서 관련 공부를 조금 더 하다가 새로운 프로젝트를 시작할 것 같습니다.
2월 안에 새로운 포스팅으로 돌아오겠습니다.

profile
iOS Developer

0개의 댓글