~ tilde * asterisk, star ' apostrophe, qutation mark, quote ` backtick, grave accent - hyphen, dash " double qutation mark, double quoutes ! exclamation _ underscore , comma @ at + plus sign . dot # number sign, hash, sharp = equals sign / slash $ Dollar sign | vertical bar, pipe () round bracket, parentheses % percent \ backslash {} culry braket, brace ^ caret ; semicolon [] square bracket & am..
처음 스위프트 UI를 사용하면 죄다 Struct로 구성되는 것을 보고 조금 익숙하지 않을 수 있습니다. 그러나 계속 공부를 하다 보면 왜 그런지 알게 되는데 그 이유를 5가지로 정리해 보겠습니다. struct ContentView: View { @State private var count = 0 var body: some View { VStack { Text("Hello") } } } 1. Struct는 단순합니다. 일단 스트럭트는 클래스에 비해 가볍습니다. 그리고 구조자체가 단순합니다. 이는 값타입이기 때문에 복사도 쉽고 참조타입인 클래스보다 메모리에도 사용에도 유리합니다. 이는 성능에 영향을 주고 아무래도 스토리보드나 xib로 만들어진 커다란 객체 덩어리 보다 훨씬 가볍고 구조적으로 UI를 만들 수 ..
스위프트 UI를 하면서 느끼는 장단점이 많이 있지만 최대의 장점을 꼽으라면 아마도 프리뷰로 개발 화면을 실시간으로 확인할 수 있다는 점일 것 같습니다. 프로젝트가 점점 커질 수록 빌드해서 확인하는 시간이 늘어나기 마련인데 스위프트 UI로 아직까지 커다란 프로젝트를 진행해본적이 없어서 모르겠으나 화면 개발에 있어서 Preview는 정말 유용한 것은 사실입니다. 그런데 다른 컴퓨터 환경에서 코드를 받아 진행하려고 하면 프리뷰 크래시가 많이 일어나는 것을 확인할 수 있습니다. 코드에 문제로 크래쉬가 일어날 수도 있지만 때로는 원인을 알 수 없이 문제가 생기는 경우도 있습니다. 보통 뷰 모델을 사용해서 작업하면서 데이터를 프리뷰에 제대로 전달하지 않아서 발생하는 문제는 작업자의 문제이니 그 밖에 해결 방법을 알..
스위프트 UI 버튼 비 활성화 스위프트 UI 에서 버튼을 비 활성화는 disabled(_:) modifier를 사용해 변경할 수 있습니다. boolean 값을 가지며 true 일 경우 disabled 상태가 되며 반대인 false 일 때는 enabled 상태가 됩니다. (false 값이 기본값) 비 활성일 경우 버튼의 색상이 Gray 색으로 변경됩니다. var body: some View { VStack { Button("비 활성 버튼") { } .disabled(true) Button("활성 버튼") { } .disabled(false) } .font(.title) } 활용 예제 다음 예제에서는 두 개의 컨트롤이 있습니다. TextField 에 값이 비어 있다면 그 값을 참조하는 name을 바인딩 한 ..
배열에 배열을 추가하는 방법은 총 3가지가 있으며 선호하는 방식으로 사용할 수 있습니다. 우선 테스트를 위한 배열 2개를 만들어보겠습니다. 주의 하실 것은 첫번째 배열의 경우 mutable로 선언했다는 것입니다. 그래서 두번째 배열을 병합할 수 있습니다. var first = ["서울", "부산"] let second = ["경기", "대전"] 1. 첫번째로 append(contentsOf:) 메서드를 이용해서 이 둘을 병합할 수 있습니다. first.append(constentsOf: second) 2. 두번째로 += 연산자로 두 배열을 병합할 수 있습니다. first += second 3. 마지막으로 이 두 배열을 + 연산자로 더해서 다른 변수에 할당할 수 있습니다. let third = first ..
코틀린을 스프링 부트 프로젝트를 사용할 때 QueryDSL을 사용할 떄 2.x 와 조금 다른 부분이 있어 정리합니다. ▼ QueryDSL 플러그인 설정을 해줍니다. plugins { id("org.springframework.boot") version "3.0.6" id("io.spring.dependency-management") version "1.1.0" kotlin("jvm") version "1.7.22" kotlin("plugin.spring") version "1.7.22" // querydsl kotlin("plugin.jpa") version "1.8.21" kotlin("plugin.allopen") version "1.8.21" kotlin("kapt") version "1.8.21"..
SELECT 문 SELECT 문은 데이터베이스에서 데이터를 검색할 때 사용하는 SQL의 가장 기본적인 쿼리입니다. 조회를 위한 명령어의 구조는 다음과 같습니다, --모든 열을 포함한 조회 SELECT * FROM 테이블명; --조회할 열이름을 나열 SELECT 열1, 열2 FROM 테이블이름; 기본적인 SELECT 문 가장 기본적인 형태의 SELECT 문은 * 를 이용해 모든 열(컬럼)을 선택하는 방법입니다. SELECT * FROM students; 특정 열(컬럼)을 선택하는 SELECT 문 특정 열을 선택해서 모든 열이 노출되지 않고 필요한 열만 검색할 때 사용합니다. 보통 SELECT 문을 만들 때는 모든 열이 필요하지 않으므로 특정 열만 선택해서 검색하는 것이 일반적입니다. SELECT stude..
INSERT 문 MySQL에서 INSERT 문은 Database에 새로운 행(레코드)를 추가하는 구문입니다. 데이터베이스에 값을 입력하는 기능을 하는 문장 정도로 생각하시면 됩니다. INSERT 구문의 기본적인 형태는 다음과 같습니다. 테이블명에 데이터를 삽입하기 위한 테이블을 기입하고 각 컬럽과 이에 대응하는 값을 VALUES 에 나열하면 됩니다. INSERT INTO 테이블명 (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); INSERT 문 예제 학생이라는 테이블이 있고 학생의 이름, 나이, 이메일을 삽입하는 예제를 만들어보겠습니다. INSERT INTO students (name, email, age) VALUES ('장발..
스크롤 뷰 scrollTo 이동 SwiftUI 에서 스크롤 뷰를 강제 이동시키려면 ScrollViewReader를 통해 값을 가져와서 scrollTo 메서드를 사용해서 이동시켜야 합니다. 다음과 같이 횡으로 스크롤 되는 캘린더에서 오늘 날짜에 중앙으로 위치 시킬 수 있는 예제로 공부해 보겠습니다. 우선 화면을 드로잉 해보겠습니다. 필요한 데이터를 간단히 정의해보겠습니다. 우선 선택한 날짜가 필요하고 캘린더 객체 그리고 시작일이 필요합니다. 이번달 전체 날짜를 그리기 위해서 components 라는 변수를 선언해 해당 달의 모든 날짜를 map을 사용해서 배열 형태로 가져옵니다. struct HCalView: View { @State private var selectedDate = Date.now priva..
아이폰 개발 시 스크롤 뷰를 사용하면 델리게이터를 이용해서 스크롤의 오프셋 값을 쉽게 알 수 있습니다. 하지만 스위프트 UI를 사용하면 어떻게 가져올지 막막합니다. 특정 위치에 스크롤을 강제로 하로 싶을 때 ScrollViewReader를 사용해서 이동시킬 수는 있지만 Offset값을 실시간으로 알기 위해서는 PreferenceKey를 통해서 값을 값을 실시간으로 추적해야 합니다. PreferenceKey 프로토콜 구현 우선 위의 PreferenceKey를 구현해보겠습니다. defaultValue와 reduce 함수를 정의해줍니다. struct ScrollPreferenceKey: PreferenceKey { static var defaultValue: CGFloat = .zero static func ..
iOS 다크모드 아이폰 개발시 다크모드(Dark Mode)를 사용하면 디자인에 많은 제약이 생깁니다. 그래서 개인적으로는 처음에는 Light 모드로 만들고 앱을 다 만든 뒤 다크모드를 적용하는 것이 더 편리한 것 같습니다. ▼ Info.plist 파일을 열어서 Appearance 값을 추가하고 값을 Light로 지정하면 라이트모드로만 앱이 실행됩니다. 키값은 UIUserInterfaceStyle 입니다. UIUserInterfaceStyle Light FirebaseAppDelegateProxyEnabled UILaunchScreen UIImageName logo ITSAppUsesNonExemptEncryption UIBackgroundModes remote-notification
BETWEEN 구문 BETWEEN 구문은 데이터베이스에서 특정 범위의 값들을 선택하는 데 사용되는 SQL 구문입니다. 주로 숫자, 날짜 또는 문자열 값의 범위를 지정하여 해당 범위에 속하는 데이터를 추출하는 데 활용됩니다. 날짜를 예로 들어보면 다음과 같이 사용할 수 있습니다. 데이터베이스를 사용할 때 어디서 부터 어디까지의 범위의 데이터를 출력하고 싶을 때 사용됩니다. 대표적으로 어떤 기간내의 데이터를 출력하기 위해서 날짜와 연관해서 많이 사용됩니다. 다음 예제는 2024년 1월 1일 부터 2월 1일 사이의 데이터를 검색하기 위한 SQL입니다. SELECT * FROM [테이블 명] WHERE [컬럼명] BETWEEN '2024-01-01' AND '2024-02-01'; 다음과 같이 숫자의 범위를 통..
IN 연산자 IN 연산자는 데이터베이스에서 특정 조건을 만족하는 값들의 집합을 검색하는데 사용되는 SQL 구문입니다. 주로 WHERE 절에서 사용되며, 다수의 값 중에서 하나라도 조건을 만족하는 경우 해당 레코드를 선택합니다. 주로 WHERE 절에서 사용되며, 다수의 값 중에서 하나라도 조건을 만족하는 경우 해당 레코드를 선택합니다. SELECT * FROM [테이블명] WHERE [칼럼명] IN ([조건1], [조건2], [조건3]); IN 연산자 활용 OR를 통해서 특정 조건에 만족하는 값들의 집합을 검색해보겠습니다. 반복적인 구문을 사용해야 하기 때문에 번거롭고 가독성도 떨어집니다. SELECT * FROM users WHERE username = 'user1' OR username = 'user2..
LIKE 연산자 MySQL에서 LIKE 연산자는 패턴 매칭을 수행하는 데 사용됩니다. 이 연산자는 문자열의 일부 또는 전체를 비교하여 특정 패턴을 가진 데이터를 검색하는 데 유용합니다. SELECT * FROM [테이블명] WHERE LIKE [조건] LIKE 연산자 패턴 % : 글자숫자를 정해주지않음(EX 컬럼명 LIKE '홍%') _ : 글자숫자를 정해줌(EX 컬럼명 LIKE '홍_동') LIKE 연산자와 % 기호를 사용하는 경우, 패턴 매칭이 데이터베이스에서 모든 레코드에 대해 수행되어야 하기 때문에 성능에 영향을 미칠 수 있습니다. 일반적으로 다음과 같은 점을 고려할 수 있습니다: 인덱스 활용 여부 %로 시작하는 패턴 매칭은 인덱스를 사용하기 어려울 수 있습니다. 왜냐하면 와일드카드가 문자열의 처..
맥을 사용해서 개발을 하다보면 디폴트 값으로 F1, F2 키가 기능 키로 매핑되어 있는 것을 확인할 수 있습니다. 특히나 크롬을 사용할 때 F12 키를 이용하는 경우가 많습니다. 하지만 그 외에는 F12를 잘 쓰지 않는다면 기본 맥 키보드의 설정이 더 편리할 수 있습니다. 선택적으로 다음 두 가지 방식으로 크롬 인스펙터 개발 화면을 사용할 수 있습니다. 1. 키보드 설정을 변경 ▼ 맥 설정 화면으로 이동해서 키보드 단축키를 선택합니다. ▼ 기능 키 메뉴로 이동해서 F1, F2 등의 키를 표준 기능 키로 사용 스위치를 활성화 해줍니다. 2. 단축키를 활용 맥에서는 다음 키를 사용해서 크롬의 인스펙터를 켤 수 있습니다. ⌘ + ⌥ + i 저는 개인적으로 2번째 방법으로 사용합니다. 기본적으로 지원하는 키이기..
안드로이드에서 리스트 뷰를 생성할 때 Adapter를 통해서 데이터를 바인딩해서 생성하는 방법을 알아보았습니다. 이번에는 간단한 예제를 만들때 어댑터를 만들지 않고 XML을 구성하여 직접 리스트 뷰 entries 속성을 통해 바인딩하는 방법을 알아보도록 하겠습니다. res/values 에 새로운 파일을 추가해서 데이터를 XML로 구성합니다. name을 myarray로 지정합니다. LIST1 LIST2 LIST3 위에서 만든 XML 데이터를 바인딩하기 위해서 리스트 뷰 에 @array/myarray 로 android:entries 에 값을 대입합니다. MainActivity onCreate 함수에 리스트 뷰 이벤트만 추가해줍니다. override fun onCreate(savedInstanceState: ..
예전에는 안드로이드에서 뷰에 대한 참조를 하려면 findViewById를 사용해야 했습니다. 그런데 사용되는 XML의 참조 객체가 많아질 수록 사용하기 불편할 뿐더러 반복되는 코드가 지져분해지기 쉽습니다. Butter knife나 extension을 통해 불편함을 해소하긴 했지만 버전 3.6 이상 부터는 안드로이드 뷰 바인딩을 통해 좀 더 편리하게 뷰에 있는 객체에 참조할 수 있게 되었습니다. findViewById를 사용할 경우 단점 느린 속도 타입 캐스팅에 따른 예외 사용자 실수로 Null 참조 자동 생성되는 파일 만약 뷰 바인딩(View Binding)을 사용하게 된다면 다음과 같이 ViewBinding 을 구현하는 임의의 파일들이 생성됩니다. Activity 클래스와 매핑 되는 클래스로 별도로 작..
뷰 모델 생성 뷰 모델을 생성합니다. 이름은 UsersViewModel 이고 ObservableObject를 상속합니다. 다음 두 개의 속성을 @Publised 래퍼로 가지고 있습니다. users : 통신의 결과 값인 User 객체의 배열 isLoading : 통신 중을 확인하는 Boolean 값 fetchUsers()라는 함수를 만들어서 통신 결과 값 데이터를 반환합니다. final class UsersViewModel: ObservableObject { @Published var users: [User] = [] @Published var isLoading = false func fethUsers() async throws { isLoading = true defer { isLoading = fals..
아이폰과 마찬가지로 모바일 환경에서 가장 많이 사용되는 형태의 UI가 리스트입니다. 안드로이드 리스트 뷰는 안드로이드에서 가장 많이 사용되는 컴포넌트 중에 하나로 다음과 같은 특징을 가지고 있습니다. 레이아웃과 같은 뷰 그룹에 속함 어뎁터(Adapter)를 통해 데이터와 리스트 뷰를 연결 오래전부터 사용 가능 했으며 API Level 1 부터 존재 프래그먼트를 사용할 경우 this 컨텍스트를 사용할 수 없기 때문에 getActivity() 함수를 사용 프래그먼트를 사용할 경우 LayoutInflater를 사용해 뷰를 가져옴 리스트 뷰 생성 아이디가 listview1 인 리스트 뷰를 선언한다. 데이터 정의 다음과 같이 데이터를 정의한다. class MainActivity : AppCompatActivity..
스위프트 Charts 라이브러리 iOS 개발을 하다보면 다음과 같은 차트 라이브러리를 많이 사용하게 됩니다. 차트 라이브러리를 사용하게 되면 그중에 ValueFormatter를 커스텀 해야 할 때가 있습니다. 텍스트의 크기나 라벨의 문구를 반복적으로 수정하는 일이 필요할 때 사용하며 때에 따라 알맞게 사용하면 됩니다. https://github.com/danielgindi/Charts/tree/master GitHub - danielgindi/Charts: Beautiful charts for iOS/tvOS/OSX! The Apple side of the crossplatform MPAndroidChart. Beautiful charts for iOS/tvOS/OSX! The Apple side of ..