'분류 전체보기'에 해당되는 글 235건

  1. 2021.03.04 MVVM 디자인 패턴
  2. 2021.03.03 Table View
  3. 2021.03.03 Class / 상속 / 생성자
  4. 2021.03.03 Closure
  5. 2021.03.02 Structure / Protocol
  6. 2021.03.01 Array / Dictionary / Set
  7. 2021.02.26 Function / Optional
  8. 2021.02.26 While / if / Repeat / for / Switch
  9. 2021.02.25 Tuple / Bool / Scope
  10. 2021.02.24 버튼 관련 코드

MVVM 디자인 패턴

Swift 2021. 3. 4. 11:26

MVVM

- Model View ViewModel

 

리팩터링

- 기술 부채를 줄이고, 재사용 가능하면서 유지보수 비용을 적게 하기 위해 코드를 수정하는 과정

 

MVC

- Model View Controller

 

 

Cocoa Touch Class

import UIKit

// MVVM

// Model
// BountyInfo 만들기

// View
// - ListCell에 필요한 정보를 ViewModel에게서 받기
// - ListCell은 ViewModel로 부터 받은 정보로 뷰 업데이트

// ViewModel
// BountyViewModel을 만들고 뷰 레이어에서 필요한 메서드 만들기
// BountyInfo들의 모델 가지고 있기

class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let viewModel = BountyViewModel()
    let bountyList = [30000000, 50, 5000000, 500000000, 10000000, 15000000, 200000000, 350000000]
    
    // segue를 수행하기 직전에 수행하는 것에 대해서 준비하는 메서드
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            
            let vc = segue.destination as? DetailViewController
            if let index = sender as? Int {
                
                let bountyInfo = viewModel.bountyInfo(at: index)
                vc?.viewModel.update(model: bountyInfo)
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
 
    
    // UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.numOfBountyInfoList
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell else {
            return UITableViewCell()
        }
        
       let bountyInfo = viewModel.bountyInfo(at: indexPath.row)
        cell.update(info: bountyInfo)
        return cell
    }
    
    // UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("\(indexPath.row)")
        performSegue(withIdentifier: "showDetail", sender: indexPath.row)
    }
}

// custom cell 생성
class ListCell: UITableViewCell {
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
    
    func update(info: BountyInfo) {
        imgView.image = info.image
        nameLabel.text = info.name
        bountyLabel.text = "\(info.bounty)"
    }
}

// ViewModel
class BountyViewModel {
    let bountyInfoList: [BountyInfo] = [
        BountyInfo(name: "brook", bounty: 30000000),
        BountyInfo(name: "chopper", bounty: 50),
        BountyInfo(name: "franky", bounty: 5000000),
        BountyInfo(name: "luffy", bounty: 500000000),
        BountyInfo(name: "nami", bounty: 10000000),
        BountyInfo(name: "robin", bounty: 15000000),
        BountyInfo(name: "sanji", bounty: 200000000),
        BountyInfo(name: "zoro", bounty: 350000000)
    ]
    
    // 순위 정하기
    var sortedList: [BountyInfo] {
        let sortedList = bountyInfoList.sorted { prev, next in
            return prev.bounty > next.bounty
        }
        
        return sortedList
    }
    
    var numOfBountyInfoList: Int {
        return bountyInfoList.count
    }
    
    func bountyInfo(at index: Int) -> BountyInfo {
        return sortedList[index]
    }
}

 

 

 

Cocoa Touch Class

import UIKit

// MVVM

// Model
// BountyInfo 만들기

// View
// - ImgView, nameLabel, bountyLabel
// - View들은 ViewModel을 통해서 구성

// ViewModel
// DetailViewModel
// 뷰 레이어에서 필요한 메서드 만들기
// BountyInfo들의 모델 가지고 있기

class DetailViewController: UIViewController {
    
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
     
    let viewModel = DetailViewMomdel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateUI()
    }
    
    func updateUI() {
        if let bountyInfo = viewModel.bountyInfo {
            imgView.image = bountyInfo.image
            nameLabel.text = bountyInfo.name
            bountyLabel.text = "\(bountyInfo.bounty)"
        }
    }
    
    // close 버튼을 누르면 창이 닫힘
    @IBAction func close(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }
}

class DetailViewMomdel {
    var bountyInfo: BountyInfo?
    
    func update(model: BountyInfo?) {
        bountyInfo = model 
    }
}

 

 

 

Cocoa Touch Class

import UIKit

// Model
struct BountyInfo {
    let name: String
    let bounty: Int
    
    var image: UIImage? {
        return UIImage(named: "\(name).jpg")
    }
    
    init(name: String, bounty: Int) {
        self.name = name
        self.bounty = bounty
    }
}

'Swift' 카테고리의 다른 글

뮤직 앱  (0) 2021.03.13
CollectionView  (0) 2021.03.06
Table View  (0) 2021.03.03
버튼 관련 코드  (0) 2021.02.24
채팅 앱 구조의 이해와 테이블 뷰 활용  (0) 2021.02.18
Posted by khon98
,

Table View

Swift 2021. 3. 3. 23:05

테이블 뷰 생성 후 셀 설정 할 수 있음

여러 아이템을 리스트 형태로 보여주고 싶을 때 사용

 

이미지 사진 이름과 코드에 입력한 이미지 이름이 다르면 이미지 출력이 안됨

 

	// 한 섹션에 Row가 몇개 들어갈 것인가
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10 // 10개의 테이블 row 생성
    }
    
    // Cell에 들어갈 데이터를 입력하는 Function
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FirstCell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }

 

 

TableView_4

 

 

더보기
import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    // 두 섹션 앞에 header를 달아서 분리
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        switch section {
        case 0:
            return "[커피]"
        case 1:
            return "[Coffee]"
        default:
            return ""
        }
    }
    
    // 두 정보를 기본으로 하여 테이블 뷰의 데이터를 컴퓨터가 작성
    // 테이블 뷰의 한 섹션당 몇 개의 셀을 담을 것인지를 Return 해줘야 하는 메서드
    // 각 섹션에 몇 개의 Cell이 들어가는지를 반환하는 메서드, 인자로 전달되는 section값에 따라 반환값을 달리해주면 됨
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return self.korean.count
        case 1:
            return self.english.count
        default:
            return 0
        }
    }
    
    // 각 row에 해당하는 cell을 Return 해줘야 하는 메서드
    // 테이블 뷰에 사용될 모든 Cell들을 반환하는 메서드, 이 메서드의 인자로 IndexPath가 전달, 이 값에서 접근자(.)으로 어떤 section과 row에 들어갈 cell을 원하는지 알 수 있음, 각 Section과 Row에 알맞는 Cell을 반환해주면 됨
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        let text: String = indexPath.section == 0 ? self.korean[indexPath.row] : self.english[indexPath.row]
        cell.textLabel?.text = text
        
        return cell
    }
    
    // 한글, 영어 2개의 섹션을 사용하기 위해, 이에 대한 정보를 전달
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
    

    @IBOutlet weak var tableView: UITableView!
    
    let cellidentifier: String = "cell"
    
    let korean: [String] = ["에스프레소", "아메리카노", "카페라떼"]
    let english: [String] = ["espresso", "americano", "cafe latte"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

 

 

현상금 리스트 만들기

더보기

Cocoa Touch Class

import UIKit

class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let nameList = ["브룩", "쵸파", "프랑키", "몽키 D.루피", "나미", "니코 로빈", "상디", "롤로노아 조로"]
    let bountyList = [30000000, 50, 5000000, 500000000, 10000000, 15000000, 200000000, 350000000]
    
    // segue를 수행하기 직전에 수행하는 것에 대해서 준비하는 메서드
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            let vc = segue.destination as? DetailViewController
            if let index = sender as? Int {
                vc?.name = nameList[index]
                vc?.bounty = bountyList[index]
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
 
    
    // UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return bountyList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell else {
            return UITableViewCell()
        }
        
        let img = UIImage(named: "\(nameList[indexPath.row]).jpg")
        cell.imgView.image = img
        cell.nameLabel.text = nameList[indexPath.row]
        cell.bountyLabel.text = "\(bountyList[indexPath.row]) "
        return cell
    }
    
    // UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("\(indexPath.row)")
        performSegue(withIdentifier: "showDetail", sender: indexPath.row)
    }
}

// custom cell 생성
class ListCell: UITableViewCell {
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
}

 

 

 

Cocoa Touch Class 2

import UIKit

class DetailViewController: UIViewController {
    
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
    
    var name: String?
    var bounty: Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateUI()
    }
    
    func updateUI() {
        if let name = self.name, let bounty = self.bounty {
            let img = UIImage(named: "\(name).jpg")
        imgView.image = img
        nameLabel.text = name
        bountyLabel.text = "\(bounty)"
        }
    }
    
    // close 버튼을 누르면 창이 닫힘
    @IBAction func close(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }
}

'Swift' 카테고리의 다른 글

CollectionView  (0) 2021.03.06
MVVM 디자인 패턴  (0) 2021.03.04
버튼 관련 코드  (0) 2021.02.24
채팅 앱 구조의 이해와 테이블 뷰 활용  (0) 2021.02.18
로그인 화면 동적 변환 구조  (0) 2021.02.17
Posted by khon98
,

object = structure와 class형태로 구현할 수 있음

 

structure

- value 타입

- 할당될 때 copy를 하게 됨

- stack에 저장

- 빠름

- 두 object를 같다, 다르다로 비교해야 하는 경우

- copy 된 각 객체들이 독립적인 상태를 가져야 하는 경우

- 코드에서 오브젝트의 데이터를 여러 스레드 걸쳐 사용할 경우

 

class

- reference 타입

- 할당할 때 reference 주소를 공유

- heap에 저장

- 느림

- 두 오브젝트의 인스턴스 자체가 같음을 확인해야 할 때

- 하나의 객체가 필요하고, 여러 대상의 의해 접근되고 변경이 필요한 경우

struct PersonStruct {
    var firstName: String
    var lastName: String
    var fullName: String {
        return "\(firstName) \(lastName)"
    }
    
    mutating func uppercaseName() {
        firstName = firstName.uppercased()
        lastName = lastName.uppercased()
    }
}

// mutating은 class에서는 사용하지 않음
class PersonClass {
    var firstName: String
    var lastName: String
    
    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
    
    var fullName: String {
        return "\(firstName) \(lastName)"
    }
    
    func uppercaseName() {
        firstName = firstName.uppercased()
        lastName = lastName.uppercased()
    }
}


var PersonStruct1 = PersonStruct(firstName: "kh", lastName: "on")
var PersonStruct2 = PersonStruct1

var PersonClass1 = PersonClass(firstName: "kh", lastName: "on")
var PersonClass2 = PersonClass1

PersonStruct2.firstName = "k"
PersonStruct1.firstName
PersonStruct2.firstName

PersonClass2.firstName = "k"
PersonClass1.firstName
PersonClass2.firstName

PersonClass2 = PersonClass(firstName: "khon", lastName: "01")
PersonClass1.firstName
PersonClass2.firstName

PersonClass1 = PersonClass2
PersonClass1.firstName
PersonClass2.firstName

 

 

 

상속

// 상속
struct Grade {
    var letter: Character
    var points: Double
    var credits: Double
}

class Person {
    var firstName: String
    var lastName: String
    
    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
    
    func printMyName() {
        print("my name is \(firstName) \(lastName)")
    }
}

class Student: Person {
    var grades : [Grade] = []
}

let khon = Person(firstName: "khon", lastName: "01")
let khon02 = Student(firstName: "khon01", lastName: "02")

khon.firstName
khon02.firstName

khon.printMyName()
khon02.printMyName()

let math = Grade(letter: "B", points: 8.5, credits: 3)
let history = Grade(letter: "A", points: 9.5, credits: 4)

khon02.grades.append(math)
khon02.grades.append(history)
khon02.grades.count


class StudentAthelete: Student {
    var minimumTrainingTime: Int = 2
    var trainedTime: Int = 0
    
    func train() {
        trainedTime += 1
    }
}

class FootballPlayer: StudentAthelete {
    var footballTeam = "man U"
    
    override func train() {
        trainedTime += 2
    }
}

var athelete1 = StudentAthelete(firstName: "yuna", lastName: "kim")
var athelete2 = FootballPlayer(firstName: "heung", lastName: "son")

athelete1.firstName
athelete2.firstName

athelete1.grades.append(math)
athelete2.grades.append(history)

athelete1.minimumTrainingTime
athelete2.minimumTrainingTime


// athelete1.footballTeam 오류 발생
athelete2.footballTeam

athelete1.train()
athelete1.trainedTime

athelete2.train()
athelete2.trainedTime

// upper casting
athelete1 = athelete2 as StudentAthelete
athelete1.train()
athelete1.trainedTime

// down casting
if let son = athelete1 as? FootballPlayer {
    print("team: \(son.footballTeam)")
}

 

 

 

생성자

// 생성자
struct Grade {
    var letter: Character
    var points: Double
    var credits: Double
}

class Person {
    var firstName: String
    var lastName: String
    
    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}

class Student: Person {
    var grades : [Grade] = []
    
    override init(firstName: String, lastName: String) {
        super.init(firstName: firstName, lastName: lastName)
    }
    
    convenience init(student: Student) {
        self.init(firstName: student.firstName, lastName: student.lastName)
    }
}

class StudentAthelete: Student {
    var minimumTrainingTime: Int = 2
    var trainedTime: Int = 0
    var sports: [String]
    
    init(firstName: String, lastName: String, sports: [String]) {
        
        // phase 1 / 자식, 부모 클래스 프로퍼티 세팅
        self.sports = sports
        super.init(firstName: firstName, lastName: lastName)
        
        // phase 2 / 자신이 가지고 있는 메서드 호출 가능
        self.train()
    }
    
    // 간략하게 사용
    convenience init(name: String) {
        self.init(firstName: name, lastName: "", sports: [])
    }
    
    func train() {
            trainedTime += 1
        }
    }

class FootballPlayer: StudentAthelete {
    var footballTeam = "man U"
    
    override func train() {
        trainedTime += 2
    }
}


let student1 = Student(firstName: "khon", lastName: "01")
let student1_1 = Student(student: student1)
let student2 = StudentAthelete(firstName: "khon", lastName: "02", sports: ["football"])
let student3 = StudentAthelete(name: "khon03")

'Swift > 문법' 카테고리의 다른 글

lazy  (0) 2021.04.01
Property / Method  (0) 2021.03.04
Closure  (0) 2021.03.03
Structure / Protocol  (0) 2021.03.02
Array / Dictionary / Set  (0) 2021.03.01
Posted by khon98
,

Closure

Swift/문법 2021. 3. 3. 17:15

Closure

- 함수처럼 기능을 수행하는 코드 블록

- 이름이 없는 메서드

- 함수는 Closure의 한 가지 타입

- Closure는 크게 3가지 타입이 있음

1. Global 함수

2. Nested 함수

3. Closure Expressions

 

First Class Type

- 변수에 할당할 수 있다

- 인자로 받을 수 있다

- 리턴할 수 있다

import UIKit

// Closure
// { (param) -> return type {
//    statement
// }

var Closure: (Int, Int) -> Int = { a, b in
    return a * b
}
let result = Closure(5, 2)



func operate(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    let result = operation(a, b)
    return result
}
operate(a: 5, b: 3, operation: Closure)



var addOperate: (Int, Int) -> Int = { a, b in
    return a + b
}
operate(a: 10, b: 3, operation: addOperate)



operate(a: 10, b: 2) { a, b in
    return a / b
}

let voidClosure: () -> Void = {
    print("Void Closure")
}
voidClosure()


// Capturing Value
var count = 0

let incrementer = {
    count += 1
}

incrementer()
incrementer()
count



// 간단한 클로저
let simpleClosure = {
    
}
simpleClosure()



// 코드 블럭을 구현한 클로저
let simpleClosure1 = {
    print("Hello")
}
simpleClosure1()



// 인풋 파라미터를 받는 클로저
let simpleClosure2: (String) -> Void = { name in
    print("my name is \(name)")
}
simpleClosure2("khon")



// 값을 return 하는 클로저
let simpleClosure3: (String) -> String = { name in
    let message = "Hello my name is \(name)"
    return message
}
let result1 = simpleClosure3("khon")
print(result1)



// 클로저를 파라미터로 받는 함수 구현
func someSimpleClosure(SimpleClosure: () -> Void) {
    print("함수에서 호출")
    SimpleClosure()
}
someSimpleClosure(SimpleClosure: {
    print("Closure")
})



// Trailing Closure
// 마지막 클로저는 생략 가능
func SomeSimpleClosure(message: String, SimpleClosure: () -> Void) {
    print("Message is \(message)")
    SimpleClosure()
}

// 생략 전 코드
// SomeSimpleClosure(message: "Hi", SimpleClosure: {
//    print("it's Closure")
// })

// 생략 후 코드
SomeSimpleClosure(message: "Hi") {
    print("it's Closure")
}

'Swift > 문법' 카테고리의 다른 글

Property / Method  (0) 2021.03.04
Class / 상속 / 생성자  (0) 2021.03.03
Structure / Protocol  (0) 2021.03.02
Array / Dictionary / Set  (0) 2021.03.01
Function / Optional  (0) 2021.02.26
Posted by khon98
,

Structure와 Class의 차이

- Structure는 Value 타입, Class는 Reference타입

 

Structure

import UIKit

// Structure

// 내 위치에서 가까운 스토어 찾기

// 거리구하는 함수
// func distance(current: (x: Int, y: Int), target: (x: Int, y: Int)) -> Double {
func distance(current: Location, target: Location) -> Double {
    let distanceX = Double(target.x - current.x)
    let distanceY = Double(target.y - current.y)
    let distance = sqrt(distanceX * distanceX + distanceY * distanceY)
    return distance
}

struct Location {
    let x: Int
    let y: Int
}

struct Store {
    let loc: Location
    let name: String
    let deliveryRange = 2.0
    
    func isDeliverable(userLoc: Location) -> Bool {
        let distanceToStore = distance(current: userLoc, target: loc)
        return distanceToStore < deliveryRange
    }
}

// 현재 스토어 위치
let store1 = Store(loc: Location(x: 3, y: 5), name: "cu")
let store2 = Store(loc: Location(x: 4, y: 6), name: "gs")
let store3 = Store(loc: Location(x: 1, y: 7), name: "seven")

// 가장 가까운 스토어 구해서 프린트 하는 함수
// func printStore(currentLocation:(x: Int, y: Int), stores:[(x: Int, y: Int, name: String)]) {
func printStore(currentLocation: Location, stores: [Store]) {
    var storeName = ""
    var storeDistance = Double.infinity
    var isDeliverable = false
    
    for store in stores {
        let distanceToStore = distance(current: currentLocation, target: store.loc)
        storeDistance = min(distanceToStore, storeDistance)
        if storeDistance == distanceToStore {
            storeName = store.name
            isDeliverable = store.isDeliverable(userLoc: currentLocation)
        }
    }
    print("store: \(storeName), isDeliverable: \(isDeliverable)")
}

// stores array 세팅, 현재 내 위치 세팅
let myLocation = Location(x: 2, y: 2)
let stores = [store1, store2, store3]

// 현재 가장 가까운 스토어 출력
printStore(currentLocation: myLocation, stores: stores)






// 강의 이름, 강사 이름, 학생 수를 가지는 struct 생성
struct Lecture {
    let name: String
    let Instructor: String
    let Student: Int
}

// 강의 array와 강사 이름을 받아서, 강사의 강의 이름을 출력하는 함수 생성
func printLecture(from instructor: String, lectures: [Lecture]) {
     var lectureName = ""

     for lecture in lectures {
         if instructor == lecture.Instructor {
             lectureName = lecture.name
         }
     }
    
//    let lectureName = lectures.first { $0.Instructor == instructor }?.name ?? ""
    print("강사님 강의는 \(lectureName)입니다")
}

// 강의 3개 만들고 강사 이름으로 강의 찾기
let lec1 = Lecture(name: "ios", Instructor: "khon", Student: 5)
let lec2 = Lecture(name: "android", Instructor: "khon01", Student: 3)
let lec3 = Lecture(name: "Reading Book", Instructor: "khon02", Student: 1)
let lectures = [lec1, lec2, lec3]

printLecture(from: "khon", lectures: lectures)

 

 

Protocol

- 지켜야 할 약속

- 서비스를 이용해야 할 때 할 일들의 목록

- CustomStringConvertible 프로토콜을 정의하면 사용자가 정의한 형태로 출력

import UIKit

// Protocol
// 강의 이름, 강사 이름, 학생 수를 가지는 struct 생성
struct Lecture: CustomStringConvertible {
    var description: String {
        // 원하는 lec을 입력하면 해당 강의 이름과 강사 명 출력
        return "Title: \(name), Instructor: \(Instructor)"
    }
    let name: String
    let Instructor: String
    let Student: Int
}

// 강의 array와 강사 이름을 받아서, 강사의 강의 이름을 출력하는 함수 생성
func printLecture(from instructor: String, lectures: [Lecture]) {
     var lectureName = ""

     for lecture in lectures {
         if instructor == lecture.Instructor {
             lectureName = lecture.name
         }
     }
    
//    let lectureName = lectures.first { $0.Instructor == instructor }?.name ?? ""
    print("강사님 강의는 \(lectureName)입니다")
}

// 강의 3개 만들고 강사 이름으로 강의 찾기
let lec1 = Lecture(name: "ios", Instructor: "khon", Student: 5)
let lec2 = Lecture(name: "android", Instructor: "khon01", Student: 3)
let lec3 = Lecture(name: "Reading Book", Instructor: "khon02", Student: 1)
let lectures = [lec1, lec2, lec3]

printLecture(from: "khon", lectures: lectures)
print(lec1)

'Swift > 문법' 카테고리의 다른 글

Class / 상속 / 생성자  (0) 2021.03.03
Closure  (0) 2021.03.03
Array / Dictionary / Set  (0) 2021.03.01
Function / Optional  (0) 2021.02.26
While / if / Repeat / for / Switch  (0) 2021.02.26
Posted by khon98
,

Array

- 같은 타입만 담아야 함

- 순서가 있는 경우, 순서를 알면 유용할 때 Array 사용

// Array
// Array 사용법
//var Array1: [Int] = [1, 2, 3, 4]
//var Array2: Array<Int> = [1, 2, 3, 4]

// Array에 값을 추가 하고 싶을때 append 사용
var Array: [Int] = [2, 4, 6, 8]
Array.append(10)

// 여러 개의 값을 넣을 때
Array += [12, 14, 16]
Array.append(contentsOf: [18, 20])

// Array에 값이 있으면 false 없으면 true
//Array = []
let isEmpty = Array.isEmpty

// element가 몇 개 있는지 알고 싶을 때
Array.count

// 첫 번째 값을 알고 싶을때, 마지막 값을 알고 싶을 때는 last
// 값이 있을수도 있고 없을수도 있기 때문에 옵셔널 타입임
print(Array.first)

let FirstElement = Array.first

if let FirstElement = Array.first {
    print("first elements: \(FirstElement)")
}

// 해당 Array의 최소, 최대 값을 알고 싶을 때
Array.min()
Array.max()

// 해당 인덱스의 값을 알고 싶을 때
var firstElement = Array[0]
var secondElement = Array[1]
var tenthElement = Array[9]

let firstThree = Array[0...2]

// 해당하는 값이 있는지 알고 싶은 경우
Array.contains(3)
Array.contains(4)

// 특정 인덱스를 삽입
Array.insert(0, at: 0) // 0을 0번째 인덱스에 삽입

// 특정 인덱스 삭제
Array.remove(at: 0)
Array

// 인덱스 삭제
//Array = []
//Array.removeAll()

// 인덱스 값 변경
Array[0] = -4
Array[1...3] = [-2, 0, 2]
Array

// 인덱스 스왑
Array.swapAt(0, 1)

// 원하는 값이 몇 번째 인덱스에 있는지 알고 싶을 때
for (index, num) in Array.enumerated() {
    print("idx:\(index), value:\(num) ")
}

// 앞에서 세 개의 인덱스를 없애는 법, 뒤에서 없애는 법은 dropLast
Array
let FirstThreeRemoveArray = Array.dropFirst(3)
Array
let BackFirstThreeRemoveArray = Array.dropLast(3)

// 앞에서 인덱스를 가져올 때, 뒤에서는 suffix
Array
let firstsecond = Array.prefix(2)
Array
let backfirstsecond = Array.suffix(2)

 

 

Dictionary

- Array와 다르게 순서가 없음

- Key와 Value로 이루어짐

// Dictionary 표현
var Score: [String: Int] = ["khon": 100, "khon01": 98]
//var Score: Dictionary<String, Int> = ["khon": 100, "khon01": 98]

if let score = Score["khon"] {
    score
} else {
    print("없음")
}

Score["khon02"]

// Dictionary를 빈 값으로 만드는 법
//Score = [:]

// Score에 데이터가 있는지 확인, 있으면 false 없으면 true
Score.isEmpty

// Score에 몇 개의 값이 있는지 확인
Score.count

// 데이터 업데이트
Score["khon"] = 95
Score

// 데이터 추가
Score["khon02"] = 97
Score

// 데이터 제거
Score["khon01"] = nil
Score

// key와 value 값 모두 알고 싶을때
for (name, value) in Score {
    print("\(name), \(value)")
}

// key 값만 알고 싶을 때
for key in Score.keys {
    print(key)
}

print("\n")


// 이름, 직업, 도시에 대한 딕셔너리 생성
var Dic: [String: String] = ["name": "khon", "job": "Student", "city": "seoul" ]

// 도시를 부산으로 데이터 업데이트
Dic["city"] = "busan"
Dic

// 이름과 도시만 출력하는 함수 생성
func printDic(dic:[String: String]) {
    if let name = dic["name"], let city = dic["city"] {
        print(name, city)
    } else {
        print("No")
    }
}

printDic(dic: Dic)

 

 

Set

- 순서가 없음

- 유일한 값을 가지는 타입

- 중복이 없는 유익한 아이템을 관리 할 때, 순서가 중요하지 않을 때 사용

// Set
var Array: Array<Int> = [1, 2, 1, 3]
var Set: Set<Int> = [1, 2, 1, 3] // 중복된 값은 제외하고 출력

Set.isEmpty
Set.count // 중복된 값은 제외

Set.contains(4) // 4는 없으므로 false
Set.contains(3)

Set.insert(5) // 5 추가
Set

Set.remove(1) // 1 제거
Set

'Swift > 문법' 카테고리의 다른 글

Closure  (0) 2021.03.03
Structure / Protocol  (0) 2021.03.02
Function / Optional  (0) 2021.02.26
While / if / Repeat / for / Switch  (0) 2021.02.26
Tuple / Bool / Scope  (0) 2021.02.25
Posted by khon98
,

Function / Optional

Swift/문법 2021. 2. 26. 21:48

Function

import UIKit

func printName() {
    print("My name is khon")
}
printName()
print("\n")


func multipleOfTen(value: Int) {
    print("\(value) * 10 = \(value * 10)")
}
multipleOfTen(value: 10)
print("\n")


func TotalPrice(price: Int, count: Int) {
    print("Total Price: \(price * count)")
}
TotalPrice(price: 1550, count: 10)
print("\n")

// _ 사용하면 파라미터 이름을 쓰지 않고 값을 입력 할 수 있음
func TotalPrice2(_ price: Int, _ count: Int) {
    print("Total Price2: \(price * count)")
}
TotalPrice2(5, 10)
print("\n")

// 한글도 사용할수 있음
func TotalPrice3(가격 price: Int, 개수 count: Int) {
    print("총 가격: \(price * count)")
}
TotalPrice3(가격: 6000, 개수: 5)
print("\n")

// price 값을 1500으로 고정
func TotalPrice4(price: Int = 1500, count: Int) {
    print("Total Price4: \(price * count)")
}

TotalPrice4(count: 10)

// 고정된 값을 변경해서 사용할수 있음
TotalPrice4(price: 2000, count: 20)


// Int형으로 return
func TotalPrice5(price: Int, count: Int) -> Int {
    let TotalPrice5 = price * count
    return TotalPrice5
}
let calculatedPrice = TotalPrice5(price: 20000, count: 16)
calculatedPrice


// 성, 이름을 받아서 Fullname을 출력하는 함수
func fullName1(firstName: String, lastName: String) {
    print("\(firstName) \(lastName)")
}
fullName1(firstName: "k1", lastName: "hon")



// 함수의 파라미터 이름을 제거하고 fullname 출력하는 함수
func fullName2(_ firstName: String, _ lastName: String) {
    print("\(firstName) \(lastName)")
}
fullName2("k2", "hon")



// 성, 이름을 받아서 fullname return 하는 함수
func fullName3(firstName: String, lastName: String) -> String {
    return "\(firstName) \(lastName)"
}
let printFullName = fullName3(firstName: "k3", lastName: "hon")
print("\(printFullName)")



// 오버로드
// 함수 이름이 같지만 안에 타입이나 내용이 다를 때
func TotalPrice(price: Int, count: Int) {
    print("Total Price: \(price * count)")
}
TotalPrice(price: 5, count: 5)

func TotalPrice(price: Double, count: Double) {
    print("Total Price: \(price * count)")
}
TotalPrice(price: 1.3, count: 10.2)


// In / out
// 파라미터 안에 있는 값은 constant 값이라 변경이 불가능 그래서 값을 변경하고 싶을때는 inout을 사용
var value = 50
func inoutFunc(_ value: inout Int) {
    value += 1
    print("\(value)")
}
inoutFunc(&value)


// 파라미터 값을 넘기기
func add(_ a: Int, _ b: Int) -> Int {
    return a + b
}

func subtract(_ a: Int, _ b: Int) -> Int {
    return a - b
}

var function = add
function(5, 3)
function = subtract
function(10, 3)

func printResult(_ function: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    let result = function(a, b)
    print(result)
}
printResult(add, 5, 10)
printResult(subtract, 10, 5)

 

 

 

옵셔널

옵셔널 종류

1. Forced Unwrapping

- !

 

2. Optional Binding (If let / guard)

- if let은 Cyclomatic Complexity가 올라갈 수 있음

 

3. Nil coalescing

 

import UIKit

// ? 있을수도 있고 없을수도 있다 라는 뜻
var carName: String?
carName = "Tesla"

let num = Int("10")


// Forced Unwrapping
print(carName!)


// if let
if let unwrappedCarName = carName {
    print(unwrappedCarName)
} else {
    print("No Value")
}


func parsedInt(from: String) {
    if let parsedInt = Int(from) {
        print(parsedInt)
    } else {
        print("컨버팅 불가\n")
    }
}
//parsedInt(from: "100\n")
//parsedInt(from: "hello\n")


// guard
func parsedIntGuard(from: String) {
    guard let parsedIntGuard = Int(from) else {
        print("컨버팅 불가")
        return
    }
    print(parsedIntGuard)
}
parsedIntGuard(from: "1000")
//parsedIntGuard(from: "Hello")



// nil coalescing
// carName이 nil이라면 S Class를 default 값으로 넘겨줌
carName = "BMW"
let myCarName: String = carName ?? "S Class"
print("\n")



// 좋아하는 음식 이름을 담는 변수 작성 (String?)
let favoriteFood: String? = "Apple"



// 옵셔널 바인딩으로 값 확인
if let unwrappedFavoriteFood = favoriteFood {
    print(unwrappedFavoriteFood)
} else {
    print("No")
}



// 닉넴임을 받아서 출력 함수 만들기, 입력 파라미터는 String?
func nickName(name: String?) {
    guard let nickname = name else {
        print("닉네임 없음")
        return
    }
    print(nickname)
}
nickName(name: "khon")

'Swift > 문법' 카테고리의 다른 글

Structure / Protocol  (0) 2021.03.02
Array / Dictionary / Set  (0) 2021.03.01
While / if / Repeat / for / Switch  (0) 2021.02.26
Tuple / Bool / Scope  (0) 2021.02.25
고차 함수(higher order function)  (0) 2021.01.30
Posted by khon98
,
import UIKit
import Foundation

print("--- While ----")
var i = 0
while i < 10 {
    print(i)
    i += 1
}
print("\n")


print("--- While / If ---")
var z = 0
while z < 10 {
    print(z)
    if z == 5 {
        break
    }
    z += 1
}
print("\n")


print("--- Repeat ---")
var y = 0
repeat {
    print(y)
    y += 1
} while y < 10
print("\n")


print("--- For ---\n")
// 0부터 10까지
let ClosedRange = 0...10

// 0부터 9까지
let halfClosedRange = 0..<10

print("ClosedRange")
var sum = 0
for q in ClosedRange {
    print("\(q)")
    sum += q
}

print("totla sum: \(sum)")


print("\nhalfClosedRange")
var sum2 = 0
for w in halfClosedRange {
    print("\(w)")
    sum2 += w
}

print("total sum: \(sum2)")


var sinValue: CGFloat = 0
for e in ClosedRange {
    sinValue = sin(CGFloat.pi/4 * CGFloat(e))
}

// 사용되지 않는 변수는 _로 사용할 수 있음
print("\n")
let name = "khon"
for _ in ClosedRange {
    print("\(name)")
}

print("\n")
for r in ClosedRange {
    if r % 2 == 0 {
        print("짝수: \(r)")
    }
}
print("\n")

// where은 조건(t % 2 == 0)을 수행하고 맞으면 그 안에 있는 코드 실행
for t in ClosedRange where t % 2 == 0 {
    print("짝수: \(t)")
}
print("\n")

// 3만 빼고 남은 수를 출력
// 특정 부분만 빼고 싶을때 continue 사용
for t in ClosedRange {
    if t == 3 {
        continue
    }
    print("\(t)")
}
print("\n")

// 0부터 3까지 수와 5빼고 남은 수 출력
for a in ClosedRange {
    if a <= 3 {
        continue
    }
    if a == 5 {
        continue
    }
    print("\(a)")
}
print("\n")

// for문은 중첩으로 사용할수 있음
for f in ClosedRange {
    for g in ClosedRange {
        print("구구단 \(f)단 \(f) * \(g) = \(f * g)")
    }
}

print("\n--- Switch ---")
let num = 10
switch num {
case 0:
    print("0")
case 0...10:
    print("0 ~ 10")
case 10:
    print("10")
default:
    print("another")
}
print("\n")

let pet = "Bird"
switch pet {
case "Dog", "Bird":
    print("House Pet")
default:
    print("It's Bird")
}
print("\n")

let Newnum = 5
switch Newnum {
case Newnum where Newnum % 2 == 0:
    print("짝수")
default:
    print("홀수")
}
print("\n")


let Coordinate = (x: 10, y: 10)
switch Coordinate {
case (0, 0):
    print("Nothing")
case (let x, 0):
    print("x, x:\(x)")
case (0, let y):
    print("y, y:\(y)")
case (let x, let y) where x == y:
    print("Same Value x, y = x\(x), y\(y) ")
case (let x, let y):
    print("Another x, y = x\(x), y\(y)")
}

'Swift > 문법' 카테고리의 다른 글

Array / Dictionary / Set  (0) 2021.03.01
Function / Optional  (0) 2021.02.26
Tuple / Bool / Scope  (0) 2021.02.25
고차 함수(higher order function)  (0) 2021.01.30
오류 처리(error handling)  (0) 2021.01.30
Posted by khon98
,

Tuple / Bool / Scope

Swift/문법 2021. 2. 25. 23:53
import UIKit

var str = "Hello, playground"


// -----------------------------
// Tuple
let value = arc4random_uniform(100)

print("-->\(value)")

let Tuple = (x: 2, y: 3)

let x = Tuple.x
let y = Tuple.y

let (x1, y2) = Tuple
x
y
// -----------------------------


// -----------------------------
// Bool
let yes = true
let no = false

let fourthanfive = 4 > 5
let fivethanfour = 5 > 4

if fourthanfive {
    print("진실")
} else {
    print("거짓")
}

if fivethanfour {
    print("진실")
} else {
    print("거짓")
}

let a = 5
let b = 10

if a > b {
    print("a가 크다")
} else {
    print("b가 크다")
}

let name1 = "khon"
let name2 = "khon01"
let SameName = name1 == name2

if SameName {
    print("같다")
} else {
    print("다르다")
}

let newkhon01 = name2 == "khon0"
let male = false

let khonismale = newkhon01 && male
let khonormale = newkhon01 || male

let greetingmassage: String
if newkhon01 {
    greetingmassage = "Hello"
} else {
    greetingmassage = "Who are you"
}
print("msg: \(greetingmassage)")

// 3항 연산자 / 값이 참인 경우 Hello 아닌 경우 Hi
let greetingmassage1: String = newkhon01 ? "Hello" : "Hi"
print("msg \(greetingmassage1)")
// -----------------------------


// -----------------------------
// Scope
// 블럭 안에 있는 것이 하나의 Scope
// { ... scope ... }
// 근무시간이 40시간이 넘으면 추가 수당을 주는 코드
var hours = 50
let payPerHour = 10000
var salary = 0

if hours > 40 {
    let extraHours = hours - 40
    salary += extraHours * payPerHour * 2
    hours -= extraHours
}

salary += hours * payPerHour

'Swift > 문법' 카테고리의 다른 글

Function / Optional  (0) 2021.02.26
While / if / Repeat / for / Switch  (0) 2021.02.26
고차 함수(higher order function)  (0) 2021.01.30
오류 처리(error handling)  (0) 2021.01.30
익스텐션(extension)  (0) 2021.01.30
Posted by khon98
,

버튼 관련 코드

Swift 2021. 2. 24. 22:34
import UIKit

class ViewController: UIViewController {

    var currentValue = 0
    
    @IBOutlet weak var PriceLabel: UILabel!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        Refresh()
    }
    
    
    @IBAction func Refresh(_ sender: Any) {
        
        let message = "가격은 \(currentValue)입니다"
        
        // 버튼 눌렀을 때 팝업 띄우는 코드
        let alert = UIAlertController(title: "Hello", message: message, preferredStyle: .alert)
        
        // ok 버튼을 누르면 변경된 가격이 바로 화면에 나옴
        let action = UIAlertAction(title: "OK", style: .default, handler: { action in self.Refresh()})
        alert.addAction(action)
        
        // present를 통해서 alert을 띄움
        present(alert, animated: true, completion: nil)
        
    }
    
    // Refresh 버튼을 눌렀을 때 가격 변경
    func Refresh() {
        
        // 1부터 10000까지의 숫자를 랜덤으로 숫자를 가져옴
        let randomPrice = arc4random_uniform(10000) + 1
        
        // randomPrice는 UIntt32, current Value는 Int 타입이라 오류
        // randomPirce를 Int형으로 변환
        currentValue = Int(randomPrice)
        PriceLabel.text = "$\(currentValue)"
    }
}

'Swift' 카테고리의 다른 글

MVVM 디자인 패턴  (0) 2021.03.04
Table View  (0) 2021.03.03
채팅 앱 구조의 이해와 테이블 뷰 활용  (0) 2021.02.18
로그인 화면 동적 변환 구조  (0) 2021.02.17
팝업 레이아웃  (0) 2021.02.16
Posted by khon98
,