[iOS 어플 만들기] 나만의 보안 키보드 만들기

정환우·2021년 1월 3일
0

iOS

목록 보기
5/24
post-thumbnail

결과물

이러한 보안 키보드를 만들고, 세자리 마다 콤마(,)를 찍게 할 것이다. 이 방법은 내가 앞서 만들었던 계산기 만들때에도 굉장히 유용하게 쓰일 것 같다.

파일 만들기

캡처1
일단 왼쪽에 보면 CustomKeyboard.swiftCustomKeyboard.swift 파일이 있다. 이 두 파일을 만들어줘야하는데, CustomKeyboard.swift 파일은 캡처화면 처럼 Cocoa Touch Class파일을 생성하면 된다.
이 때, 상속받는 클래스가 UIViewController가 아니라 UIView이어야 한다.

그리고CustomKeyboard.xib 파일은 아래 User Interface 항복에서 View 파일을 생성해주면 된다.

여기서 View와 Storyboard의 차이점은 간단하게 Storyboard 파일은 Controller만 연결할 수 있고 View는 UI종류는 다 연결이 가능하다. 파일을 생성후 CustomKeyboard.swift 클래스를 파일 인스펙터에서 연결해 주어야 한다.

레이아웃

캡처 2

여기서 보면, 오른쪽 아래에 View 항목에 User Interaction Enabled 체크 항목이 있는데 이것을 체크해제해주면 버튼을 눌러도 아무런 반응이 일어나지 않는다. 이 사진 처럼 보안키보드 공백을 버튼으로 만든다면 저걸 해제해주면 되고, 아예 View를 삽입해버리면 이 과정은 생략해도 된다. 개인적으로는 버튼 액션보단 그냥 View가 더 깔끔하지 않을까 생각한다.

레이아웃은 간단하게 버튼 11개를 만들고 가로를 하나의 스택뷰로 묶은다음에 총 4개의 스택뷰를 다시 하나의 큰 스택뷰로 묶고 Constraints를 설정해주고 Distribution을 Fill equally로 설정하면 이렇게 나온다.

1~9까지 버튼들 함수 하나하나 생성하지말고 함수하나에 모든 버튼을 다 연결하면 된다. 이걸 몰라서 나는 계산기 만들 때 뻘짓을 했다.

(캡쳐가 너무 귀찮아서 사진 설명이 불친절한건 양해 부탁드립니다. 그냥 복습겸 쓰는거라..)

코드들

먼저 CustomKeyboard.swift파일의 코드를 살펴보겠다.

>>> CustomKeyboard.swift

import UIKit

// delegate - 기능이나 값을 위임해줌.

protocol CustomKeyBoardDelegate {
    func KeyboardTapped(str: String)
}

class CustomKeyboard: UIView {
    
    var delegate: CustomKeyBoardDelegate?   // 계속 남아있어 메모리 누수가 일어날 수 있으므로 optional로 선언.
    
    @IBAction func buttonTapped(_ sender: UIButton) {
        
        delegate?.KeyboardTapped(str: sender.titleLabel!.text!)
        
    }
    
}

여기서 가장 중요한건 protocol, delegate인데, 버튼이 눌릴 때 그 버튼의 텍스트 값을 ViewController.swift 에 전달해줘야하므로 설정한다고 보면 된다.

그리고 ViewController.swift 파일

>>> ViewController.swift


import UIKit


// 클래스에 protocol을 사용해준다고 선언을 해야함.
class ViewController: UIViewController, CustomKeyBoardDelegate {

    @IBOutlet weak var firstTextField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        // 커스텀 키보드 설정 방법.
        //firstTextField.inputView = "커스텀키보드뷰"
        
        let loadNib = Bundle.main.loadNibNamed("CustomKeyboard", owner: nil, options: nil)   // xib 파일 정보를 불러온 것.
        
        let myKeyboardView = loadNib?.first as! CustomKeyboard
        myKeyboardView.delegate = self  //이 선언문이 중요함.
        firstTextField.inputView = myKeyboardView
    }
    
    func KeyboardTapped(str: String) {
        // 키보드 눌렀을 때 호출 됨.
        
        let oldNumber = Int(firstTextField.text!)
        var newNumber = Int(str)
        
        if str == "00" && oldNumber != nil{
            newNumber = oldNumber! * 100
        }
        else if str == "000" && oldNumber != nil{
            newNumber = oldNumber! * 1000
        }
        else if oldNumber != nil{
            newNumber = newNumber! + oldNumber! * 10
        }
        
        if let hasNumber = newNumber {
            
            let numberFormatter = NumberFormatter()
            numberFormatter.numberStyle = .decimal  // 숫자를 세자리마다 쉼표로 찍어줌.
            if let formatted = numberFormatter.string(from: NSNumber(value: hasNumber)){    // if let은 optional을 벗겨준다.
            firstTextField.text = String(describing: formatted)
            }
        }
    }
}

먼저, class에 protocol을 사용하기 위해 CustomKeyBoardDelegate를 선언한다.

그리고 여기서

let myKeyboardView = loadNib?.first as! CustomKeyboard
        myKeyboardView.delegate = self  //이 선언문이 중요함.
        firstTextField.inputView = myKeyboardView

loadnib는 .xib파일을 불러온다고 생각하면 되고, 클래스에서 CustomKeyboardDelegate 를 선언해주었으니 .delegate = self 다.

그리고 inputView가 키보드 모양이므로 그걸 내 커스텀 키보드로 바꿔주는 것. 이 구문이 상당히 어려우니까 복습을 좀 하고 찾아봐야겠다.

그리고 쉼표를 찍어주는 numberFromatter 사용법은

if let hasNumber = newNumber {
            
            let numberFormatter = NumberFormatter()
            numberFormatter.numberStyle = .decimal  // 숫자를 세자리마다 쉼표로 찍어줌.
            if let formatted = numberFormatter.string(from: NSNumber(value: hasNumber)){    // if let은 optional을 벗겨준다.
            firstTextField.text = String(describing: formatted)
            }
        }

구글링을 해도 이거와 큰 차이가 없다. if let은 optional 변수를 자동으로 unwrap 해주는 것은 처음 알았다. 나머지는 변수 장난들. 그리고 쉼표를 찍어주는 것은 String형식으로 반환되는 것을 꼭 참고해야 할 것 같다.

꼭 혼자 다시 만들어보기!

0개의 댓글