728x90
728x90
SMALL
프로토콜(Protocol)이란?
특정 작업 혹은 기능에 적합한 메소드, 프로퍼티, 기타 요구사항들의 청사진
특징
- 클래스, 구조체, 열거형에서 채택될 수 있음
- 여러개의 프로토콜을 동시에 채택할 수 있음
- 프로토콜은 이름과 타입만이 지정될 뿐 상세한 내용은 구현하지 않는다
예제
protocol FullyNamed {
static var firstName : String { get set }
var mddleName : String { get set }
var fullName: String { get }
func getName() -> String
mutating func toggleName()
init(middleName: String)
}
예제 결과화면
구현
- Money.swift
import Foundation
protocol MoneyProtocol {
var totalMoney:Int { get }
var count:Int { get }
// 데이터 입력
func enterData(moeny:Int, count:Int)
// 계산 로직
func calculate() -> Int
// 남은 금액
func remain() -> Int
// 결과 출력
func printResult() -> String
}
class DivideMoney : MoneyProtocol {
var totalMoney: Int = 0
var count: Int = 0
func enterData(moeny: Int, count: Int) {
totalMoney = moeny
self.count = count
}
func calculate() -> Int {
return totalMoney / count
}
func remain() -> Int {
return totalMoney - calculate() * count
}
func printResult() -> String {
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .decimal
guard let totalMoney = numFormatter.string(from: NSNumber(value: totalMoney)),
let result = numFormatter.string(from: NSNumber(value: calculate())) else { return "" }
var msg = ""
msg = "총 금액 : \(totalMoney)원\n인원 : \(count)명\n1명당 내야할 금액 : \(result)원"
if remain() != 0 {
guard let other = numFormatter.string(from: NSNumber(value: remain())) else { return "" }
msg += "\n나머지 금액 : \(other)원"
}
return msg
}
}
class GatherMoney : MoneyProtocol {
var totalMoney: Int = 0
var count: Int = 0
func enterData(moeny: Int, count: Int) {
totalMoney = moeny
self.count = count
}
func calculate() -> Int {
return totalMoney / count
}
func remain() -> Int {
return totalMoney - calculate() * count
}
func printResult() -> String {
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .decimal
var msg = ""
guard let totalMoney = numFormatter.string(from: NSNumber(value: totalMoney)),
let result = numFormatter.string(from: NSNumber(value: calculate())) else { return "" }
msg = "총 기간 : \(count)개월\n총 금액 : \(totalMoney)원"
if remain() == 0 {
msg += "\n\(count)개월간 내야할 금액 : \(result)원"
} else {
guard let other = numFormatter.string(from: NSNumber(value: calculate() + remain())) else { return "" }
msg += "\n\(count-1)개월간 내야할 금액 : \(result)원\n마지막 달에 내야할 금액 : \(other)원"
}
return msg
}
}
- MoneyProtocol : 전체 금액, 카운트 변수의 정의 / 데이터 입력, 계산, 남은 금액 반환, 결과 출력 함수만 정의 되어 있는 프로토콜
- DivideMoney : MoneyProtocol을 채택하여 입력 받은 전체 금액을 카운트로 나누어 1인당 지불해야할 금액을 계산해주는 클래스
- GatherMoney : MoneyProtocol을 채택하여 입력 받은 금액을 카운트의 기간 동안 모으기 위해서는 기간 별로 얼마씩 저금해야하는지 계산해주는 클래스
- ContentView.swift
import SwiftUI
struct ContentView: View {
@State private var viewIndex = 0
@State private var people = 0
@State private var money = ""
@State private var isShow = false
@State private var msg = ""
private var divider:DivideMoney = DivideMoney()
@FocusState private var isFocused: Bool
// tapGesture 조건부사용
private var tapGesture: some Gesture {
isFocused ?
(TapGesture().onEnded {
isFocused = false
}) : nil
}
var body: some View {
TabView(selection: $viewIndex) {
ZStack {
VStack {
// 나누어야할 금액입력
TextField("나눌 금액을 입력하세요", text: $money)
.focused($isFocused)
.frame(width: 300)
.textFieldStyle(.roundedBorder)
.keyboardType(.numberPad)
.padding(18)
// 나눌 인원설정
Stepper(value: $people, in: 1...10) {
Text(people < 2 ? "나누어야할 인원" : "\(people)명")
}
.frame(width: 300)
// 계산버튼
Button {
showResult()
} label: {
Text("계산하기")
}
.buttonStyle(.bordered)
.foregroundColor(.white)
.background(.black)
.cornerRadius(10)
.padding(60)
// 결과 메세지 창
Text(msg)
.foregroundColor(.red)
}
.padding(EdgeInsets(top: 30, leading: 18, bottom: 30, trailing: 18))
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle())
.gesture(tapGesture)
.tabItem {
Image(systemName: "person.3.sequence.fill")
Text("돈나누기")
}
.tag(0)
GaterViewView()
.tabItem {
Image(systemName: "arrow.up.bin.fill")
Text("돈모으기")
}.tag(1)
}
}
// 결과보여주기
func showResult() {
msg = ""
// 입력 예외처리
if money.isEmpty { return }
guard let inputMoney = Int(money) else { return }
if people < 2 || inputMoney < 1 { return }
// 계산 후 메세지 출력
divider.enterData(moeny: inputMoney, count: people)
msg = divider.printResult()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
money를 n명이 나눌 때 1인 당 지불해야하는 금액을 계산해주는 화면
- GatherView.swift
import SwiftUI
struct GaterViewView: View {
@State private var month = 0
@State private var money = ""
@State private var isShow = false
@State private var msg = ""
private var gather:GatherMoney = GatherMoney()
@FocusState private var isFocused: Bool
// tapGesture 조건부사용
private var tapGesture: some Gesture {
isFocused ?
(TapGesture().onEnded {
isFocused = false
}) : nil
}
var body: some View {
ZStack {
VStack {
// 나누어야할 금액입력
TextField("모을 금액을 입력하세요", text: $money)
.focused($isFocused)
.frame(width: 300)
.textFieldStyle(.roundedBorder)
.keyboardType(.numberPad)
.padding(18)
// 기간 설정
Stepper(value: $month, in: 0...10) {
Text(month < 1 ? "기간 설정" : "\(month)개월")
}
.frame(width: 300)
// 계산버튼
Button {
showResult()
} label: {
Text("계산하기")
}
.buttonStyle(.bordered)
.foregroundColor(.white)
.background(.black)
.cornerRadius(10)
.padding(60)
// 결과 메세지 창
Text(msg)
.foregroundColor(.red)
}
.padding(EdgeInsets(top: 30, leading: 18, bottom: 30, trailing: 18))
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle())
.gesture(tapGesture)
}
// 결과보여주기
func showResult() {
msg = ""
// 입력 예외처리
if money.isEmpty { return }
guard let inputMoney = Int(money) else { return }
if month < 1 || inputMoney < 1 { return }
// 계산 후 메세지 출력
gather.enterData(moeny: inputMoney, count: month)
msg = gather.printResult()
}
}
struct GaterViewView_Previews: PreviewProvider {
static var previews: some View {
GaterViewView()
}
}
money를 특정 기간 동안 모을 때 1개월 당 저금해야할 금액을 계산해주는 화면
참고사이트
728x90
728x90
LIST