TIL

15일차 TIL

h_luz 2024. 3. 18. 21:21

원래 노션에 작성했었는데.. 노션보다 티스토리나 벨로그가 나을 것 같아서 티스토리로 옮겼다! 다른 내용들은 차근차근 옮길 예정

이전에 TIL에 사용하던 노션 링크

https://www.notion.so/TIL-Today-I-Learned-36df8aa1ca944e499daee4a8bdc4f4ad

https://www.notion.so/TIL2-Today-I-Learned-4f0918d5320047ccbea10b23c1233ca2

 

Swift 알고리즘 및 언어공부
//35. 부족한 금액 계산하기

import Foundation
func solution(_ price:Int, _ money:Int, _ count:Int) -> Int{
    var answer:Int = -1
    var sum:Int = 0
    var result:Int = 0
    for i in 1...count {
        sum = price * i
        result = result + sum
    }
    answer = money - result
    return answer > 0 ? 0 : -answer
}

난 코드 줄이기는 글렀다 … ㅠ

뭔가 함수나 수학적으로 간단하게 풀어내고 싶은데 결국 뭔가 주절주절 해버린다.. 머리가 나빠서..

ㅠㅠ 그래서 다른 사람의 풀이를 분석해보려고 한다

//다른 사람 풀이
import Foundation

func solution(_ price:Int, _ money:Int, _ count:Int) -> Int64{
    var total = 0
    for i in 1...count { total += (i * price) }

    var answer:Int64 = -1
    answer = (total > money) ? Int64(total - money) : 0

    return answer
}

비슷한 코드지만 더 간단하다. 나는 쓸데없이 변수를 사용하고, 같은 걸 두 번씩 적는 일이 많은 것 같다.

다음 문제를 풀 때는 주의해야겠다고 생각했다.

그리고 타입.. 항상 주의할 것!

 

import Foundation

func solution(_ price:Int, _ money:Int, _ count:Int) -> Int{
    return max((count + 1) * count / 2 * price - money , 0)
}

이건 굉장히 수학적으로 풀어낸 코드인데

보면서 와 어떻게 이렇게 생각했지.. ㅠ 했다. 난 바보다..

그리고 max 함수는 비교값 중 큰 수를 반환하는 특성을 갖고 있는데, 그걸 이용해서 한 문장으로 코드를 완료한 것도 대단하다고 생각했다.

 

//36. 문자열 다루기 기본

func solution(_ s:String) -> Bool {
    if s.count != 4 && s.count != 6 { return false }
    for i in s {
        if i.isNumber == false { return false }
    }
    return true
}

일단 나는 이렇게 풀이했다. 전에 야구게임 코드 만들때 사용했던 isNumber가 생각나서 사용했다.

문자열에는 배열의 특성이 있다는 것을 잊지않길 ㅜㅜ

 

그리고 어김없이 다른 사람의 풀이

func solution(_ s:String) -> Bool {
    return (Int(s) != nil && (s.count == 4 || s.count == 6)) ? true : false
}

이렇게 한 줄 코드를 만들다니 진짜.. 똑똑하다..

나도 문자열 s를 Int로 변환했을 때 오류가 생기면 false를 반환하면 되는 거 아닌가? 이런 생각을 하기는 했지만

Int(s) != nil 이게 참이면 true 반환. 이런 식으로 풀다니 .. ㅠ swift를 잘 활용하는 똑똑한 사람..

나도 조금 더 깊이 생각해봐야겠다고 생각했다.

 

그리고 또 다른 풀이

func solution(_ s:String) -> Bool {
    if (s.count != 4) && (s.count != 6) { return false }
    return s.allSatisfy({ $0.isNumber })
}

 이건 allSatisfy를 사용했는데, 뭔가 간단하게 작성한 것 같아서 가져왔다 ! 그럼 allSatisfy에 대해서 알아보자

 

allSatisfy

: Collection의 모든 요소가 특정 조건을 만족시키는지 알고 싶은 경우 사용 (Array, Dictionary, Set 타입에 사용)

 

위에 s.allSatisfy( {$0.isNumber} ) 을 예시로 보면,

s 문자열에 0번째 값부터 숫자가 맞는지 아닌지 즉, 특정 조건을 만족시키는지 확인하고 만약에 만족시키지 못하면 false를 반환한다.

 

다른 예시를 보면

let arr = ["abcdef", "12345", "문자열"]
let bool = arr.allSatisfy { $0.count > 2 }
print(bool) // true

모든 문자열의 길이가 2보다 크기 때문에 true를 반환하는 것.

https://ios-development.tistory.com/951

 


 

IOS 앱 개발 입문

 

UILabel : 하나 이상의 정보 텍스트 줄을 표시하는 보기 (A view that displays one or more lines of informational text)

 

UILabel 생성 및 설정

let label = UILabel() //label 상수로 사용하기 위한 초기화

 

텍스트 설정 ( .text )

label.text = "안녕하세요,UILabel 예제입니다." // ""안에 문자들을 출력한다.

 

폰트 설정 ( .font )

label.font = UIFont.systemFont(ofSize: 18) //크기 설정

 

텍스트 색상 설정 ( .textColor )

label.textColor = UIColor.black //검정색으로 변경

 

텍스트 정렬 ( .textAlignment )

label.textAlignment = .center //가운데 정렬
  • .left : 왼쪽 정렬
  • .right : 오른쪽 정렬
  • .natural : 지역화 기준으로 정렬 (left와 비슷하게 느껴지지만, 지역화가 아랍어인 경우 .right 정렬 )
  • .justified : 양쪽 정렬, 행 맞추기
    (left와 비슷하지만, linebreak 설정에 의해 행이 바뀔 때 들쭉날쭉해지는 문단의 마지막 부분을 뷰 넓이에 맞춰서 글자 간격을 조정함)

 

텍스트 줄 바꿈 설정 ( .numberOfLines / .lineBreakMode)

label.numberOfLines = 2 //2줄로 표시 (0으로 설정하면 자동 줄 바꿈)
label.lineBreakMode = .byTruncatingTail
//텍스트가 너무 긴 경우, 끝에 ... 표시 후 줄 바꿈

 

Try

UILabel 실습

UILabel의 사이즈 설정 ( .frame )

: CGRect를 사용해서 x, y, width, height의 사이즈를 설정할 수 있다.

label.frame = CGRect(x: 150, y: 200, width: 100, height: 100)

 

마지막 줄이 중요한데, view에 addSubview() 메서드로 label을 추가해 주어야 보인다.

self.view.addSubview(label)

 


 

UIImageView : UIImage를 보여주기 위한 커스텀 뷰 ( UIImage: 이미지를 위한 데이터를 가지고 있는 객체 )

 

UIImageView 생성

let imageView = UIImageView() //UIImageView를 사용하기 위한 상수 생성

 

이미지 설정

let image1 = UIImage(named: "exampleImage") //image 상수에 "exampleImage"라는 이미지넣기

 

이미지 뷰에 어떤 이미지 넣을지 설정

imageView.image = image1

 

이미지 뷰 사이즈 설정 ( .frame )

imageView.frame = CGRect(x:50, y:100, width:200, height:150)

 

이미지 비율? 설정 ( .contentMode )

imageView.contentMode = .scaleAspectFit //이미지 비율을 유지하며 크기 맞춤

 

  • scaleAspectFit : 비율을 유지하며 View 크기에 맞춤. (남는 영역은 투명하게)
  • scaleAspectFill : 비율을 유지하며, View 크기에 맞추는데, 빈 영역 없이 확장한다. (일부가 잘릴 수 있음)
  • scaleToFill : 비율을 변경하여 View 크기에 맞게 확장.

즉, Aspect = 비율유지 / Fill = 빈 영역 없이 / Fit = 화면에 맞게

 

 

Try

UIImageView 실습

* 마찬가지로 self.view.addSubview()를 설정해서 이미지를 띄워야 한다.

* 이 경우 이미지의 이름은 exampleImage이다.

 


 

UITextField : 사용자로부터 텍스트를 입력받기 위해 사용됨

 

UITextField 생성

let textField = UITextField()

 

텍스트 입력 유도 메시지 ( placeholder )

textField.placeholder = " 텍스트를 입력하세요 "

 

텍스트 필드 모양 ( borderStyle )

textField.borderStyle = .roundedRect // 둥근 테두리

 

텍스트 필드 모양의 종류

.roundedRect
.bezel
.line

 

.none (default 값)

 

키보드 타입 ( keyboardType )

textField.keyboardType = .default // 텍스트 필드를 누르면 키보드가 밑에서 위로 나옴 (기본)

https://ikkison.tistory.com/18 키보드 타입에 대해서 자세히 설명되어 있다.

 

텍스트 보안 ( isSecureTextEntry )

textField.isSecureTextEntry = false //텍스트필드 보안 x

true로 설정하면, 비밀번호 입력 시 글자가 검은 동그라미?로 보이는 것처럼 설정할 수 있고,

화면 녹화 시 보이지 않도록 하는 보안 기능을 사용할 수 있다.

( default 값은 false )

 

키보드 리턴 타입 설정 ( returnKeyType )

textField.returnKeyType = .done

보통 텍스트 필드에 입력을 하기 위한 키보드가 나오면 return으로 되어있는 데

그 return을 done으로 바꿔주는 설정이다.

https://zeddios.tistory.com/128 보면 잘 설명이 되어 있다.

 

Try

 


 

UIButton : 사용자가 터치하여 상호작용 할 수 있는 UI요소

 

버튼 생성

let button = UIButton(type: .system) //시스템 스타일의 버튼

 

버튼 타입

.system(default)

.infoDark

.infoLight

.contactAdd

외에도 여러 가지 있는 것 같음.

 

버튼에 표시될 텍스트

button.setTitle("버튼을 눌러보세요", for: .normal)

for 에 .normal 은 무엇을 뜻하는 걸까..?

 

버튼 색 설정

button.backgroundColor = UIColor.blue //버튼 배경 색상
button.setTitleColor(UIColor.white, for: .normal) //버튼 텍스트 색상

 

버튼 크기

button.frame = CGRect(x:50, y:100, width:200, height:50)

 

버튼에 대한 액션 설정

button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

@objc func buttonTapped() {
	print("버튼이 눌렸습니다.")
}

탭 했을 때 "버튼이 눌렸습니다."가 print 되는 함수를 만들어서 action에 넣어준다.

 

Try

UIButton 실습

* 마찬가지로 self.view.addSubview(button) 필수

*버튼을 누르면 "버튼이 눌렸습니다."가 print 된다.

 


 

UISwitch : On/Off 상태를 표시하고 전환하는 데 사용되는 UI 요소

 

스위치 생성

let mySwitch = UISwitch()

 

스위치 초기 상태

mySwitch.isOn = true
//켜져있음. 값을 false로 하면 꺼져있다는 뜻.

 

스위치 색상

mySwitch.onTintColor = UIColor.blue //켜져있을 때 배경 색상
mySwitch.thumbTintColor = UIColor.black //썸네일 색상

 

스위치에 따른 표시되는 이미지

mySwitch.onImage = UIImage(named: "onImage") //켰을 때
mySwitch.offImage = UIImage(named: "offImage") //껐을 때

 

스위치 상태에 따른 action

mySwitch.addTarget(self, action: #selector(switchValueChange), for: .valueChanged)

@objc func switchValueChange(_ sender: UISwitch){
        if sender.isOn {
            print("Switch is On")
        } else {
            print("Switch is Off")
        }
    }

 

Try

UISwitch 실습

 

UISlider : 값의 범위를 가지고 사용자가 원하는 값을 (슬라이드 해서) 선택할 수 있는 UI 요소

 

슬라이더 생성

let slider = UISlider()
slider.value = 50 //슬라이더 초기값
slider.minimumValue = 0 //슬라이더 최소값
slider.maximumValue = 100 //슬라이더 최대값

 

슬라이더 색상 설정

slider.minimumTrackTintColor = UIColor.red //왼쪽 트랙 색상
slider.maximumTrackTintColor = UIColor.blue //오른쪽 트랙 색상
slider.thumbTintColor = UIColor.white //썸네일 색상

 

슬라이더 action

slider.addTarget(self, action: #selector(sliderValueChanged(_:)), for: .valueChanged)

@objc func sliderValueChanged(_ sender: UISlider){
	print("slider value: \(sender.value)")
}

for에 들어있는 valueChanged는 ' 값이 바뀌면, '이라는 의미!

즉, 값이 바뀌면 action을 수행한다는 뜻

 

그렇다면 이 함수 sliderValueChanged(_:)에서 언더바와 땡땡은 무슨 의미일까..?

 

Try

UISlider 실습

값이 바뀌면 슬라이더의 값을 출력하는 action을 수행한다.

 


 

UISegmentedControl : 여러 개의 세그먼트로 구성된 컨트롤. ( 원하는 옵션 선택 가능 )



세그먼트 컨트롤 생성

let datas = ["Option1","Option2","Option3"] // 세그먼트 컨트롤에 들어갈 옵션들
let segmentedControl = UISegmentedControl(items: datas)

segmentedControl.selectedSegmentIndex = 0 //초기 세그먼트 인덱스
//즉, Option1이 초기 선택된 옵션이 된다.

segmentedControl.isMomentary = false
//선택 표시를 유지할 지 아니면 다른 옵션 선택 시 변경될지 여부 설정

 

세그먼트 컨트롤 색상

segmentedControl.tintColor = UIColor.blue

 

세그먼트 action 처리

segmentedControl.addTarget(self, action: #selector(segmentValueChanged(_:)), for: .valueChanged)

@objc func segmentValueChanged(_ sender: UISegmentedControl){
	print("Selected segment index: \(sender.selectedSegmentIndex)")
}

 

Try

UISegmentedControl 실습

 

 

오늘 배운 것들을 한꺼번에 다 외우진 못하겠지만 이렇게 한 번씩 써놓고, 실습해 보면 나중에 써먹어야 할 때 '어, 이런 거 있었던 것 같은데' 이런 식으로 생각나서 TIL이 좋은 것 같다.

알고리즘 풀 때도 매번 새로운 함수를 알아가고, TIL에 적는데 그 함수들도 다 외우진 못하지만 이럴 때 뭐 쓰는 거 있었던 것 같은데.. 이렇게 떠올리게 되는 것 같음! 굳굳..

 

오늘 화면 그리기 강의는 뭔가 슉슉 넘어가는 느낌이긴 하지만 내가 궁금했던 것들이어서 흥미로웠다.

실습한 거 외에도 어떤 다른 방식으로 사용되는 지도 궁금하고, 이것저것 찾아보다 보니까 벌써 시간이.. ㅠ

 

과제도 어려워 보이던데.. 내일은 모든 강의 끝내고 카운터 만들기 도전해 봐야겠다.

'TIL' 카테고리의 다른 글

20일차 TIL  (3) 2024.03.25
19일차 TIL  (3) 2024.03.22
18일차 TIL  (2) 2024.03.21
17일차 TIL  (1) 2024.03.20
16일차 TIL  (2) 2024.03.19