반응형

UITextField, UITextView 입력 시 키보드가 활성화될 때 키보드에 가려지지 않도록 하는 방법을 알아보도록 한다.

아래 샘플은 UITableView에서 입력 시 키보드에 가려지지 않도록 처리하는 예제이다.

class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var tableView: UITableView!

    private var activeTextField: UITextField?
    private var activeTextView: UITextView?

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        registerForKeyboardNotifications()
    }
	... 중간 생략 ...
    
    
    // 활성화된 TextView 입력 필드를 추적 및 갱신
    func textFieldDidBeginEditing(_ textField: UITextField) {
        activeTextField = textField
        activeTextView = nil
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        activeTextField = nil
    }
    
    
	// 활성화된 TextView 입력 필드를 추적 및 갱신
    func textViewDidBeginEditing(_ textView: UITextView) {
        activeTextView = textView
        activeTextField = nil
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        activeTextView = nil
    }
}

extension ViewController {
	// 키보드가 나타날 때, 키보드가 내려갈 때 이벤트 등록
    func registerForKeyboardNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(_:)), name: UIResponder.keyboardDidShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
	
    // 키보드가 나타날 때 실행되며, 현재 활성화된 입력 필드가 키보드에 의해 가려지지 않도록 스크롤
    @objc func keyboardWasShown(_ notification: NSNotification) {
        guard let userInfo = notification.userInfo,
              let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }

        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height

        let insets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
        tableView.contentInset = insets
        tableView.scrollIndicatorInsets = insets

        var aRect = self.view.frame
        aRect.size.height -= keyboardHeight

        if let activeTextField = activeTextField, let textFieldRect = activeTextField.superview?.convert(activeTextField.frame, to: tableView) {
            if !aRect.contains(textFieldRect.origin) {
                tableView.scrollRectToVisible(textFieldRect, animated: true)
            }
        } else if let activeTextView = activeTextView, let textViewRect = activeTextView.superview?.convert(activeTextView.frame, to: tableView) {
            if !aRect.contains(textViewRect.origin) {
                tableView.scrollRectToVisible(textViewRect, animated: true)
            }
        }
    }
	
    // 키보드가 내려갈 때 
    @objc func keyboardWillBeHidden(_ notification: NSNotification) {
        tableView.contentInset = .zero
        tableView.scrollIndicatorInsets = .zero
    }
}

 

반응형
블로그 이미지

SKY STORY

,
반응형

UITextField 컨트럴을 사용하여 숫자를 입력 받을 경우 입력된 숫자에 자동으로 콤마를 추가되도록 구현해 보았다. 또한 숫자 이외의 문자입력 방지 및 Int형 변환처리등을 구현하였다.

import Foundation
import UIKit

class MainViewController: UIViewController {

    @IBOutlet weak var tfAmount: UITextField!
    
    override func viewDidLoad() {
    	super.viewDidLoad()
        
        // 키보드 타입 설정 (storyboard에서 설정 가능)
        tfAmount.delegate = self
        tfAmount.keyboardType = .numbersAndPunctuation  // 숫자와 구두점이 포함된 키보드로 설정
        tfAmount.clearButtonMode = .whileEditing        // 편집하는 동안 'clear' 버튼 활성화
        tfAmount.clearsOnBeginEditing = true            // 편집 시작 시 내용 지우기
    }
    
    import UIKit

extension MainViewController : UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField == self.tfJJRefundAmount {
            // 숫자 이외의 문자는 입력되지 않도록 처리
            let invalidCharacters = CharacterSet.decimalDigits.inverted
            return string.rangeOfCharacter(from: invalidCharacters) == nil
        }
        return true
    }
    
    func textFieldDidChangeSelection(_ textField: UITextField) {
        if textField == self.tfAmount {
            // 입력시 자동으로 ',' 추가
            if let text = textField.text?.replacingOccurrences(of: ",", with: "") {
                if let number = Int(text) {
                    let formatter = NumberFormatter()
                    formatter.numberStyle = .decimal
                    textField.text = formatter.string(from: NSNumber(value: number))
                    self.tfAmount.tag = number // Int형 값을 tag에 저장.
                }
            }
        }
    }

    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
        if textField == self.tfAmount && textField.text?.isEmpty == true {
            // 필요한 경우 추가 처리
        }
        return true
    }
    
    func textFieldShouldClear(_ textField: UITextField) -> Bool {
        textField.text = ""
        return true
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()    // 키보드 내리기
        
        if textField == self.tfAmount && textField.text?.isEmpty == true {
            // 필요한 경우 추가 처리
        }
        return true
    }
}

 

다음 코드는 'OK' 버튼을 선택했을 때 입력된 금액을 Int형 접근하는 사용 예이다.

extension MainViewController {
    
    @IBAction func okButtonTapped(_ sender: UIButton) {
	    guard let amountText = tfAmount.text else {
            print("금액 입력이 올바르지 않습니다.")
            return
        }
        
        // 금액 (Int형 사용을 위해 tag값 사용)
        var amount = self.tfAmount.tag 
        // 배송비
        var shippingCost = 3000 
        // 총 금액 계산
        let totalAmount = amount + shippingCost
        
        print("총 금액 : \(totalAmount)원")
    }
}

 

 

반응형
블로그 이미지

SKY STORY

,