텍스트 필트에서의 입력과 Delegate
텍스트 필드의 속성 Placeholder
- 위치 : Attribute Inspector > Placeholder
- Placeholder : P텍스트 필드에 아무것도 입력하지 않았을 때 나오는 값
키보드 스타일 설정
- Keyboard Type : Number Pad로 설정하면 숫자로 된 키보드가 나오게 된다
텍스트 필드 변경처리
조건
회씨를 입력하면 섭씨로 변경처리되도록 설정
-> 컨트롤 레이어와 모델 레이어에서 처리한다.
컨트롤레이어 ConversionViewController.swift 생성
// import Foundation
import UIKit
class ConversionViewControlller : UIViewController {
}
ViewController > indentifier Inspector > Class를 ConversionViewController로 선택
ConversionViewControlle.swift수정
// import Foundation
import UIKit
class ConversionViewControlller : UIViewController {
@IBOutlet var celsiusLabel: UILabel!
@IBAction func fahrenheitEditingChanged(textField: UITextField){
celsiusLabel.text = textField.text
}
}
ConversionViewController선택 > ceisiusLabel을 드래그하여 Label "100"에 드롭
IBAction 연결
텍스트 필드 선택 > Connection Inpector > Sent Events의 Editing Changed를 ConversionViewController에 Dreg and Drop > fahrenheitEditingChanged 선택
-ConversionViewController.swift 수정
// import Foundation
import UIKit
class ConversionViewControlller : UIViewController {
@IBOutlet var celsiusLabel: UILabel!
@IBAction func fahrenheitEditingChanged(textField: UITextField){
if let text = textField.text, !text.isEmpty{
celsiusLabel.text = textField.text
}
else{
celsiusLabel.text = "???"
}
}
}
-실행화면
키보드 숨기기
UITextField의 두 함수
- becomeFirstResponder : 키보드를 나타나게 한다. UITextField를 선택하면 자동 호출된다.
- resignFirstResponder : 키보드를 사라지게 한다.
컨트롤들을 포함하고 있는 View를 클릭하면 키보드가 사라지도록 설정한다.
ConvertionViewController.swift 코드 수정
// import Foundation
import UIKit
class ConversionViewControlller : UIViewController {
@IBOutlet var celsiusLabel: UILabel!
@IBOutlet var textField: UITextField!
@IBAction func fahrenheitEditingChanged(textField: UITextField){
if let text = textField.text, !text.isEmpty{
let fahrenheitValue = Double(text)
let celsiusValue = (fahrenheitValue! - 32.0) * (5.0 / 9.0)
celsiusLabel.text = String(celsiusValue)
}
else{
celsiusLabel.text = "???"
}
}
@IBAction func dismissKeyboard(sender: AnyObject){
textField.resignFirstResponder()
}
}
변수 fatrenheitValue 데이터 타입: Double
Tap Gesture Recognizer을 ViewController밑에 Drop > Tap Gesture Recognizer을 ViewController의 dismissKeyboard와 연결
온도 변환 구하기
ConvertionViewController.swift 코드 수정
// import Foundation
import UIKit
class ConversionViewControlller : UIViewController {
@IBOutlet var celsiusLabel: UILabel!
@IBOutlet var textField: UITextField!
@IBAction func fahrenheitEditingChanged(textField: UITextField){
if let text = textField.text, !text.isEmpty{
let fahrenheitValue = Double(text)
let celsiusValue = (fahrenheitValue! - 32.0) * (5.0 / 9.0)
celsiusLabel.text = String(celsiusValue)
}
else{
celsiusLabel.text = "???"
}
}
@IBAction func dismissKeyboard(sender: AnyObject){
textField.resignFirstResponder()
}
}
변수 fatrenheitValue 데이터 타입
숫자 포맷 지정자
ConvertionViewController.swift 코드 수정
// import Foundation
import UIKit
class ConversionViewControlller : UIViewController {
@IBOutlet var celsiusLabel: UILabel!
@IBOutlet var textField: UITextField!
@IBAction func dismissKeyboard(sender: AnyObject){
textField.resignFirstResponder()
}
// 1
@IBAction func fahrenheitEditingChanged(textField: UITextField){
if let text = textField.text, let value = Double(text){
fahrenheitVlaue = value
}
else{
fahrenheitVlaue = nil
}
}
// 3
func updateCelsiusLabel(){
if let value = celsiusValue{
//celsiusLabel.text = "\(value)"'
//celsiusLabel.text = String.init(format: "%.2f", value)
celsiusLabel.text = numberFormatter.string(from: NSDecimalNumber(decimal: Decimal(value)))
}
else {
celsiusLabel.text = "???"
}
}
// 4
var celsiusValue: Double? {
if let value = fahrenheitVlaue{
return (value - 32) * (5/9)
}
else {
return nil
}
}
// 2
var fahrenheitVlaue: Double?{
didSet{
updateCelsiusLabel()
}
}
let numberFormatter: NumberFormatter = {
let nf = NumberFormatter()
nf.numberStyle = .decimal
nf.minimumIntegerDigits = 0
nf.maximumIntegerDigits = 1 // 소수점 뒤로 최대 1개까지
return nf
}()
}
실행화면
Delegation
- callback의 객체지향적 방식이다.
- 하나의 delegation은 여러 개의 callback함수를 내포한다.
- 델리게이션은 필요한 시점에 메서드를 호출해주는 역할을 하며 이벤트가 발생할 때마다 델리게이션 내의 함수를 호출한다.
- 클래스 간 상호작용을 전달하는 간단한 접근 방식이며 클래스의 책임을 분리할 수 있다.
Delegate 패턴
위임자를 갖고 있는 객체가 다른 객체에게 자신의 일을 위임(Delegate)하는 형태의 디자인 패턴이다.
[iOS] Delegate 패턴이란 무엇일까?
유명하고 자주 사용되는 Delegate 패턴에 대해 알아봅시다.
velog.io
Protocol ( = 자바에서는 interface )
- 특정 역할을 수행하기 위한 메서드, 프로퍼티, 기타 요구사항 등의 청사진을 정의하는 것.
- 구조체, 클래스, 열거형은 프로토콜을 채택하여 특정 기능을 수행하기 위한 프로토콜의 요구사항을 구현한다.
- Swift는 프로토콜 지향 언어(Protocol-Oriented-Language)이다.
Protocol과 Interface의 차이점
Interface
- 프로퍼티의 기본값을 설정할 수 있다
- 인터페이스의 모든 메서드를 구현해야 한다.
Protocol
- 프로퍼티의 기본값을 설정하지 않는다. 프로토콜은 기능을 정의하고 제시할 뿐 스스로 기능을 구현하지 않는다.
var age: Int = 20 // 프로토콜은 기본 값 설정 불가능 -> 오류! - optional 키워드를 사용하여 선택적으로 메서드를 구현할 수 있다.
protocol Person {
var A: Int
func B(s: String)
// optional 키워드를 사용.
optional func C(status: Boolean) -> Boolean
}
class youngPerson: Person {
var A: Int = 14
func B(s: String) {
print(s)
}
}
정리
- Protocol : 정의만 할 뿐 초기값 설정이 불가능하고, optional 키워드를 통해 선택적으로 구현이 가능하다.
- Interface : 초기값 설정이 가능하고, 선택적으로 구현하는 것이 불가능하다.
알파벳 문자 허용하지 않기
UITextFieldDelegate프로토콜 추가
class ConversionViewControlller : UIViewController, UITextViewDelegate, UITextFieldDelegate {
하단 코드 추가
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{
let decimalDigits = CharacterSet.decimalDigits
for char in string.unicodeScalars{
if !decimalDigits.contains(char){
print("문자포함\n")
return false;
}
}
// '.' 사용불가
let existingTextHasDecimalSeparator = textField.text?.range(of: ".")
let replacementTextHasDecimalSeparator = string.range(of: ".")
if existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil{
return false
}
else {
return true
}
}
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
}
문자 입력 시 로그가 출력되는 것을 확인할 수 있다.
range(of:)
func range(of searchString: String) -> NSRange
- 문자열 내에서 주어진 문자열이 처음 나타나는 범위를 찾아 반환한다.
- 문자열의 특정 문자의 범위를 리턴해주는 메서드이다.
- 반환값 : NSRange형태의 문자열의 위치와 길이를 반환한다.
- options: 대소문자를 무시한다.
let str = "Hello, World!"
str.range(of: "World")
str.range(of: "world", options: [.caseInsensitive]) // 대소문자 무시
Range
- [lowerBound, upperBound) 방식으로 표현
- Swift에서의 Range는 표준 라이브러리이기 때문에 import하지 않아도 사용할 수 있다.
public struct Range<Bound: Comparable> {
public let lowerBound: Bound
public let upperBound: Bound
}
사용 예시
let range = 0..< countingUp.count
for i in range {
let string = countingUp[i]
//string
}
NSRange
- Foundation에서 제공하는 구조체 타입
- 연속적인 객체를 담고 있는 객체(String에서의 character들, Array에서의 원소들 등)에서 일정 부분을 표현하는 데 사용되는 구조체
- 시작점인 location, Range의 길이인 length로 이루어져 있고 둘 다 Int 타입이다.
- NSRange의 Range값은 [location, location + length) 방식으로 표현된다.
public struct _NSRange {
public var location: Int
public var length: Int
}
textField(_:shouldChangeCharactersIn:replacementString:)
optional func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool
- text가 변경할지에 대한 delegate요청 메서드
- range: 변경되는 문자열에 관련된 NSRange 값, 이전 배열과 비교했을 때 현재 배열에서 변경된 원소의 개수
- string: 대체 문자열
- 문자를 하나 입력할 때 : 크기가 1인 문자열
- 문자열 붙여 넣기를 수행할 때: 여러 개 문자열
- 문자열을 삭제할 때: 빈 문자열
[Swift 기초 문법] - IBAction과 IBOutlet이 뭘까
Swift 문법을 처음 공부하면서 여러 예제를 참고하다보니, 이전의 배웠던 java나 C# 등의 언어에서는 보지못했던 새로운 문법형식들이 등장해서 다소 낯설었습니다. 그래서 이런 문법들에 대해 찾
etst.tistory.com
[iOS][Swift] 프로토콜 vs 인터페이스 차이점
비슷해보이는 프로토콜과 인터페이스의 차이점입니다 !
velog.io
https://ios-development.tistory.com/688
[iOS - swift] textField(_:shouldChangeCharactersIn:replacementString:) newText 구하는 방법 (+ 문자열 처리, Range, NSRa
알아야 하는 기본 개념 Range NSRange 문자열 처리 메소드 .trimmingCharacters(In: .whitespacesAndNewlines), .replaceingCharacters(in:with:) Range half-open의 범위를 나타내고 있는 구조체 Range는 lowerB..
ios-development.tistory.com
https://soooprmx.com/swift-swift%EC%9D%98-%EB%AC%B8%EC%9E%90%EC%97%B4%EA%B3%BC-nsrange/
Swift의 문자열과 NSRange를 함께 사용하기 · Wireframe
Swift의 문자열 타입은 NSRange 타입과 호환되지 않지만, 기존의 코코아 프레임워크 내의 문자열 관련 처리 API들은 NSRange를 많이 사용한다. Swift 문자열을 이러한 API들과 사용하는 것은 매우 코드를
soooprmx.com
[Swift] String 고수가 될거야 (tistory.com)
[Swift] String 고수가 될거야
✔️ Apple 공식문서 참고 Apple Developer Documentation developer.apple.com Strings and Characters — The Swift Programming Language (Swift 5.5) Strings and Characters A string is a series of charact..
leeari95.tistory.com
https://jcsoohwancho.github.io/2019-11-17-NSRange%EC%99%80-Range/
NSRange와 Range
이번 포스트에서는 NSRange와 Swift에서 많이 쓰이는 Range에 대해서 알아보도록 하겠습니다. NSRange NSRange는 Foundation에서 제공하는 구조체 타입입니다. public struct _NSRange { public var location: Int public var l
jcsoohwancho.github.io
https://developer.apple.com/documentation/uikit/uitextfielddelegate/1619599-textfield
Apple Developer Documentation
developer.apple.com
'iOS > iOS개발' 카테고리의 다른 글
[iOS] 뷰 컨트롤러 - TapView, UIViewController 생명주기 (0) | 2022.11.16 |
---|---|
[iOS] 뷰와 뷰의 계층구조 (1) | 2022.09.24 |
[iOS] MVC구조와 오토레이아웃 / Xcode구조 (1) | 2022.09.22 |