내가 들은 영어

원래 대본 영어

Scene0

Monica : There's nothing to tell, it just some guy I work with.

Monica : There's nothing to tell! He's just some guy I work with

 

더 말할 것도 없어!, 그는 그저 같이 일하는 사람이야

 

Joey : Come on! You're going out with the Guy, There's got to be something wrong with him

Joey : C'mon, you're going out with the guy! There's gotta be something wrong with him!

 

무슨소리야, 너 그 남자랑 데이트 하잖아! 그 남자 뭔가 이상해!

 

Chandler : So, This have a Hump?, Hump and a hairpiece?

Chandler : So Does he have a hump? A Hump and a hairpiece?

 

그 사람 혹이있나? 혹 도 있고 가발도 쓰나?

 

Phoebe : Wait does he eat chock?

Phoebe : Wait does he eat chock?

 

잠깐만 그사람 분필 먹어?

 

Phoebe : Just cause, I don't want her to go through without went through with carl, oh

Phoebe : Just 'cause, I don't want her to go through what I went through with carl, oh

 

난 그저 내가 만났던 칼 같은 사람을 너가 만나지 않길 바래

 

Monica : Okay, Everybody relex, this is not even a date,  It's just two people going out to dinner, and not having sex!

Monica : Okay, Everybody relex, this is not even a date,  It's just two people going out to dinner, and not having sex!

 

다들 진정해, 이건 데이트가 아니야, 단지 두명의 사람이 만나서 저녁을 먹는거야, 밤을 보내지 않고 헤어지는 거라고!

 

Chandler : Sounds like date to me

Chandler : Sounds like date to me

 

나에겐 데이트로 들리는데.

 

모르는 단어 Check

1. hump : 혹

2. hairpiece : 가발

본 내용은 스윗한 SwiftUI 책에 있는 예제를 공부한 내용입니다.
해당 예제들에 대한 저작권은 BJpublic 에 있습니다.

 

  • 이미지에 frame 속성을 사용해도 이미지 자체의 크기를 변경해 주진 않음
  • Resizable 속성을 사용하여 이미지 크기를 변경할 수 있음
HStack {
	Image("imgFile")     // 이미지 크기는 변하지 않고, 이미지를 포함함 뷰의 크기가 변함
		.frame(width: 50, height: 50)

	Image("imgFile").resizable()    // resizable() 을 사용하여 이미지 크기 자체가 변함
		.frame(width: 200, height: 50)
}

  • frame 은 View의 속성이기 때문에 resizable 과 순서가 중요함!
  • resizable() 을 사용하여 특정 영역만 늘려주는 것도 가능함
  • 단, UIKit 처럼 ResizingMode 를 생략하면 tile 이 아니라 stretch가 기본값이 됨
HStack {
            Image("swift")
            //capInset 매개 변수에 늘어날 영역 지정. resizingMode 생략 시 stretch 적용
                .resizable(capInsets: .init(top: 0, leading: 50, bottom: 0, trailing: 0))
                .frame(width: 150, height: 150)
            
            Image("swift")
                .resizable(resizingMode: .tile)
                .frame(width: 150, height: 150)
        }

 

ContentMode

UIKIt SwiftUI 설명
Scale to Fill Default 값 종횡비와 상관없이 이미지를 늘려 표현
Aspect Fit .scaledToFit() 종횡비를 유지한 채로 표현가능한 최대로 표현
Aspect Fill .scaledToFill() 종횡비를 유지한 채로 표현하며, 이미지가 짤리거나 추가적으로 더 크게 표현

 

HStack(spacing: 30){
						// 기본값
            Image("swift").resizable().frame(width: 100, height: 150)
            
						// UIKit의 Aspect Fit 적용
            Image("swift").resizable()
                .scaledToFit()
                .frame(width: 100, height: 150)

						// UIKit의 Aspect Fill 적용            
            Image("swift").resizable()
                .scaledToFill()
                .frame(width: 100, height: 150)
        }

 

AspectRatio

  • 이미지 비율을 좀더 세부적으로 조정하기 위해 사용하는 수식어
  • 모든 콘텐츠가 적용된 상황에서 추가적으로 비율조정을 하기위해 사용
// CGFloat : 너비 / 높이 를 계산한 비율을 전달
func aspectRatio(_ aspectRatio: CGFloat? = nil, contentMode: ContentMode) -> some View

// CGSize : 너비 와 높이를 각각 설정
func aspectRatio(_ aspectRatio: CGFloat? = nil, contentMode: ContentMode) -> some View

AspectRatio 적용한 예제

HStack(spacing: 30) {
            //scaledToFit 콘텐츠 모드를 적용한 뒤, 너비가 높이보다 1.6배 비율을 가지도록 조정
            Image("swift").resizable()
                .aspectRatio(CGSize(width: 1.6, height: 1), contentMode: .fit)
                .frame(width: 150, height: 150)
            
            // scaledToFill 콘텐츠 모드를 적용한뒤, 너비가 높이보다 0.7배의 비율을 가지도록 조정
            Image("swift").resizable()
                .aspectRatio(0.7, contentMode: .fill)
                .frame(width: 150, height: 150)
                .clipped()
        }

 

ClipShape

  • 이미지를 원하는 모양으로 조정
  • 크기 또한 조정 가능
HStack(spacing: 30) {
            // 원 모양
            Image("swift").clipShape(Circle())
            
            // 이미지 크기보다 사방으로 10씩 크기를 조정한 사각형
            Image("swift").clipShape(Rectangle().inset(by: 10))
            
            // 크기와 위치를 직접 지정한 타원
            Image("swift").clipShape(Ellipse().path(in: CGRect(x: 10, y: 10, width: 80, height: 110)))
        }

 

RanderingMode

  • template : 이미지의 불투명 영역이 가진 본래의 색을 무시하고 원하는 색으로 변경
  • original : 항상 이미지의 본래 색을 유지
  • 렌더링 모드를 생략하면 시스템이 알아서 조정을 하므로, 원치않은 결과가 나오면 렌더링 모드를 지정해야함
HStack(spacing: 30) {
            // 렌더링 모드 생략 -> 시스템이 스스로 결정
            Image("swift")
            
            // 원본 이미지 색상 유지
            Image("swift").renderingMode(.original)
            
            // template 모드 적용
            Image("swift").renderingMode(.template)
        }
        .foregroundColor(.blue) // 자식 뷰 모두에게 일괄 적용

 

SF Symbol

  • 애플에서 직접 만들고 제공하는 이미지들의 모음
  • iOS 13이상부터 사용 가능
  • 벡터 기반의 이미지로, 시스템 폰트로 크기를 조정 할 수도 있음
  • 앱에서 심볼들을 확인 할 수 있으며, systemName: 으로 간단히 사용 가능
HStack(spacing: 30){
            Image(systemName: "star.circle")
            Image(systemName: "star.circle.fill")
        }

  • ImageScale 을 적용하면 크기를 지정 할 수 있다. ( 기본값 → medium )
HStack(spacing: 30) {
            Image(systemName: "star.circle").imageScale(.small)
            Image(systemName: "star.circle")
            Image(systemName: "star.circle").imageScale(.large)
        }

  • font 속성을 이용해서 크기를 조정 할 수도 있다
HStack(spacing: 30) {
            Image(systemName: "star.circle").font(.body)
            Image(systemName: "star.circle").font(.title)
            Image(systemName: "star.circle").font(.system(size: 40))
            Image(systemName: "star.circle").imageScale(.large).font(.system(size: 40))
        }

  • weight 속성을 이용하면 굵기 표현도 가능 하다
HStack(spacing: 30) {
            Image(systemName: "star.circle").font(Font.title.weight(.black))
            Image(systemName: "star.circle").font(Font.title.weight(.semibold))
            Image(systemName: "star.circle").font(Font.title.weight(.light))
            Image(systemName: "star.circle").font(Font.title.weight(.ultraLight))
        }

 

결국 SwiftUI도, UIKit 도 ,

두마리 토끼를 모두 챙겨서 Apple Developer Academy를 수료하고자 한다.

 

어쩌면 비효율 적일수도 있지만 아카데미가 끝나자마자 바로 취업전선에 뛰어들기 위해서는 그만큼 열심히 해야한다.

 

현 취업시장을 보니 확실히 SwiftUI 보다 UIKit의 중요도가 훨씬 높은것 같고,

 

애플은 결국 언젠가는 SwiftUI로 점점 변경될것이다..

 

지금당장 우선순위만 따지면 UIKit 이지만, 언젠가는 결국 SwiftUI 도 알아야한다

 

그래서 앞으로는 이렇게 공부하려고 한다.

 

월 ~ 금

기상 ~ 09:00 아침밥 먹으면서 미드시청 ( 영어공부 )

09 : 00 ~ 12 : 00     SwiftUI 공부

13 :  00 ~ 18 : 00    UIKit 공부

19 : 00 ~ 잠들기 전  그날 부족하거나 추가적으로 공부할것 , 혹은 그날 공부한 내용 정리

 

주말

문법 공부 & 알고리즘 공부

 

지켜지길..

본 내용은 스윗한 SwiftUI 책에 있는 예제를 공부한 내용입니다.
해당 예제들에 대한 저작권은 BJpublic 에 있습니다.

전체적으로 훑어보기

VStack(spacing: 30) {  // 세로 방향으로 뷰를 배열하는 컨테이너 뷰
            Text("폰트와 굵기 설정")
                .font(.title) // 폰트 설정
                .fontWeight(.black) // 폰트 굵기
            
            Text("글자색은 foreground, 배경은 background")
                .foregroundColor(.white)
                .padding()      // 텍스트 주변 여백 설정
                .background(Color.blue)
            
            Text("커스텀 폰트, 볼드체, 이탤릭체, 밑줄, 취소선")
                .font(.custom("Menlo", size: 16))
                .bold()
                .italic()
                .underline()
                .strikethrough()
            
            Text("라인 수 제한과 \\n 텍스트 정렬 기능입니다. \\n 이건 안 보입니다.")
                .lineLimit(2)
                .multilineTextAlignment(.trailing) // 다중행 문자열의 정렬 방식 지정
                .fixedSize() // 주어진 공간의 크기가 작아도 텍스트를 새략하지 않고 표현하도록 설정
            
            // 2개 이상의 텍스트를 하나로 묶어서 동시에 적용
            (Text("자간과 기준선").kerning(8) //자간
             + Text(" 조정도 쉽게 가능합니다.").baselineOffset(8)) // 기준선
            .font(.system(size: 16))

 

Text 수식어 적용의 순서의 중요성

  • Text 와 View 의 font, foregroundColor 의 정의
extention Text {
	// Text와 View 모두 있는 수식어
	public func font(_ font: Font?) -> Text
	public func foregroundColor(_ color: Color?) -> Text
	
	// Text에만 있는 수식어
	public func bold() -> Text
	public func italic() -> Text
}

extention View {
	// Text와 View 모두 있는 수식어
	public func font(_ font: Font?) -> some View
	public func foregroundColor(_ color: Color?) -> some View

	// View 에만 있는 수식어
	public func padding(
		_ edges: Edge.Set = .all,
		_ length: CGFloat? = nil
	) -> some View
}
  • Text에도, View에도 font 와 foregrountColor 가 정의되어 있다
  • 단, 반환 타입이 다름을 주시하자
  • View 에만 있거나, Text에만 있는 경우 순서가 중요하다

잘못된 순서로인한 변화 예제

Text("SwiftUi")
	.font(.title) // Text - 호출자의 타입이 Text
	.bold()       // Text
	.padding()    // View - padding 수식어 호출 이후로는 Text가 아닌 View 반환

Text("SwiftUi")
	.bold()       // Text
	.padding()    // View
	.font(.title) // View - 동일한 font 수식어를 호출해도 호출자에 따라 반환타입 다름

Text("SwiftUi")
	.padding()    // View
	.bold()       // 컴파일 오류 - View에는 bold 가 정의되어 있지 않기 때문
	.font(.title) 

Text("SwiftUi")
	.font(.title) // View
	.padding()    // View
	.bold()       // 컴파일 오류 - View에는 bold 가 정의되어 있지 않기 때문

잘못된 순서로 인한 변화 예제2

// 1번
Text("🐶🐱🐭🐹🐼").font(.largeTitle)
	.background(Color.yellow) // 배경 색상지정이 Text 크기에 따라 우선 적용
	.padding()                // 배경 색상이 적용된 Text에 padding 적용

// 2번
Text("🐶🐱🐭🐹🐼").font(.largeTitle)
	.padding()                // Text에 Padding 을 우선 적용!
	.background(Color.yellow) // padding 이 적용된 부분에 배경색상 지정

  • 1번

  • 2번

  • 보이는 것과 같이 순서에 따라 View 자체가 어떻게 그려질지 보여준다
  • 이처럼, SwiftUI에서는 수식어의 순서에 따라 오류가 날수도, 보여지는 뷰가 다를수도 있음을 유의하자

 

문제

 

풀이 코드

// 변수 선언
var inputs = readLine()!
var commandResult = ""
let commandCount = Int(readLine()!)!

for _ in 0..<commandCount {
    let command = readLine()!
    
    switch command {
    case "L":
        if !inputs.isEmpty { commandResult.append(inputs.popLast()!) }
    case "D":
        if !commandResult.isEmpty { inputs.append(commandResult.popLast()!) }
    case "B":
        if !inputs.isEmpty { inputs.removeLast() }
    default:
        inputs.append(command.last!)
    }
}

print(inputs + commandResult.reversed())

 

풀이 과정

// 변수 선언
var result = readLine()!
let commandCount = Int(readLine()!)!
var cursor = result.count

for _ in 0..<commandCount {
    let index = result.index(result.startIndex, offsetBy: cursor)
    let command = readLine()!.split(separator: " ")
    
    switch command[0] {
    case "P":
        result.insert(contentsOf: command[1], at: index)
        cursor += 1
    case "L":
        if cursor - 1 >= 0 { cursor -= 1 }
    case "D":
        if cursor + 1 <= result.count { cursor += 1 }
    default:
        if cursor > 0 {
            cursor -= 1;
            let removeIndex = result.index(result.startIndex, offsetBy: cursor)
            result.remove(at: removeIndex) }
    }
}

print(result)

처음, 위와 같은 방식으로 문제를 풀었다, 하지만 시간초과 가 발생했습니다.

이리 저리 고쳐 봤지만, 시간 초과 문제를 해결하지 못했습니다.

그래서 검색해본 결과

  1. split을 쓰면 시간이 오래걸림
  2. 내가 짠 코드에서 String.index 로 변환하고, 다시 변수 생성하고 등등의 과정으로 오랜 시간이 소요됨

이라는 결론을 낼 수 있었고, Stack 구조체를 이용하여 풀어야 한다고 생각했지만,

그런데 전에 풀었던 방식으로 구조체로 사용하게되면 string 을 각각 문자로 변환하고 그걸 또 스택에 넣어야 하는 과정속에서 또 다시 시간초과가 날 거 같아서 그냥 배열로 처리를 해주었습니다.

입력된 결과에서 현 커서의 위치가 이동될 때 마다 새로운 문자열(commandResult)에 Push 해 주거나 원 문자열에서 pop 해주면서 계산해주어 풀이했습니다.

+ Recent posts