ㅤ 오늘도 간단한 문제로 3시간을 날렸다. 이전 글에서 SwiftUI의 FullscreenCover 방식의 화면전환을 사용하려면 fullscreenDialog를 사용하면 된다고 했었는데, 여기와 관련된 문제가 발생했다. ㅤ 아래와 같은 구조로 되어있고, 화살표처럼 화면 전환을 만들고자 했다. ㅤ 여기에서, fullscreen dialog로 넘어간 2번째 줄에서는 push로 페이지를 전환한 다음에는 뒤로 pop을 할 수 없는 구조이기에 pushReplacement 같은 함수를 사용해 전환하려고 고려하고 있었다. ㅤ 그러나, fullscreenDialog 첫 페이지에서 pushReplacement 함수를 호출하니, bottomSheet 이 있는 뷰로 가버리는 문제가 있었다! 아마 추측하건데, fullscre..
ㅤ 아래와 같은 화면 전환 기능을 구현하고 싶었다. SwiftUI 에서는 아래 기능을 Fullscreen Cover 라고 부른다. 오른쪽 왼쪽으로 화면이 전환되는 Navigation과 달리 수직으로 올라오는 애니메이션이 특징이며, 모달과 달리 머리를 잡고 아래로 스크롤해도 전환이 취소가 되지 않는다. 주로 일시적인 데이터 입력이나 흐름을 벗어나서 유저가 확 집중을 해야하는 부분에서 이러한 방식을 사용한다. ㅤ ㅤ 뭔가 Navigator.push() 처럼 Navigator 하위에 함수가 있을 것이라고 생각했는데, 찾아보니 없었다. 그래서 아예 모달을 불러오는showBottomModalSheet() 함수처럼 아예 별개의 함수로 있을 거라고 생각해서 구글링을 해봤다. 그런데 띠용? Navigator.push ..
올해 초에 애플 개발자 아카데미 동문회를 갔다가 운이 좋게도 시디즈의 신제품 하이엔드 의자인 T90을 직접 사용하면서 체험해볼 수 있는 기회를 얻었다! 🥹🥹 올해는 설날부터 이런 고급진 의자에 앉아볼 기회도 생기고, 한 해가 잘 풀리려나 싶다 ㅎㅎ 나는 어릴때부터 앉은 자세가 바르지 않아 척추 측만이 있어서 허리가 쉽게 피로해지는 편이다. 이 때문에 개인적으로 허리 건강에 평소에도 신경을 쓰고있어서 PT를 받으며 운동할 때에도 ‘허리 보강운동을 더 했으면 좋겠어요’ 같은 말을 트레이너에게 요청하기도 하고, 주변 친구들에게도 척추수술 1,700만원을 외치며 친구들의 앉은 자세를 고쳐주기도 했다. 여전히 컴퓨터를 전공하면서 책상에 앉아 키보드를 두드리면서 허리에 피로감이 느껴질 때가 많고 크로스핏을 하면서 ..
ㅤ 피그마에서 디자인을 하면서, 처음에는 이런 모양의 그래프를 그리고 싶었다. ㅤ 근데, 생각보다 이걸 만드는게 잘 안보이더라. line에서 곡선을 사용해서 만들려고 하니 뭔가 계속 울퉁불퉁한 원이 되어버리고, path를 사용해서 그리자니 더 이상하고. 흠… ㅤ 뭔가 방법이 있을 것 같아서 찾아봤더니, 실제로 있더라! 아래같은 방법으로 진행하면 되는거였다. 나는 몰랐지.. 이리 쉬운건지 ㅋㅋㅋ 작년에도 똑같은 디자인을 했던 적이 있었는데, 한 번 찾아보고 할 걸 그랬다. 작년에는 path 가지고 울퉁불퉁하게 대충 원 따라 만들었던 것 같은데,, ㅤ ellipse 원을 그려준다. ㅤ 오른쪽에 있는 arc를 당겨 원하는 각도를 만들어준다. ㅤ 가운데 ratio를 당겨서 원하는 폭을 만들어준다. ㅤ 각도를 원..
오늘도 쌩고생을 했다. 매주 쌩고생거리가 계속 등장하는 것 같다. ㅜㅜ 심지어 오늘은 다트 문법에 당했다. ㅤ List 뒤에 원소를 추가하고 싶을 때는 append가 아닌 add 함수를 사용해야 한다. 블로그 글을 쓰기 위해서 가져왔는데, 이제야 함수의 차이점이 보인다. ㅤ append 쪽 설명을 읽어보면 “Insert element at the end of the [Iterable]” 이라고 되어있다. 나는 요걸 보고 철썩같이 믿고 썼는데, 아무리 디버깅을 해도 해결이 안돼서 한숨만 푹푹 쉬고 있었지… 근데 요게 문제였을 줄은 몰랐다… 파이어베이스에 복잡하게 쿼리를 날리고 결과를 조인해야 하는 기능이라 중간에 뭐가 잘못되었는지 디버거 켜놓고 값 계속 확인하면서 찾아나섰는데, 제일 마지막에 결과 합쳐서 ..
ㅤ 모브 크로스핏 7시반 사람들과 함께 갓생 챌린지를 4주동안 진행했다. 이번에 참여하기 전부터 거의 상시 진행되는 챌린지였는데, 이번에 처음 들어갔다. 이번 차수가 무려 11기라고 한다. 처음부터 꾸준히 해온 사람은 거의 1년이 넘게 갓생을 살아온 것 아닌가…? ㅤ 규칙은 간단하다. 주 1회 ~ 5회 수행할 목표를 최소 1개씩 정하고 인증을 올린다. 일요일 저녁에 이번주 결산을 하고, 성공하지 못한 목표 하나 당 5천원을 벌금으로 낸다. 매 주 끝날 때 마다 이번 주에 대한 느낀점을 간단하게 남긴다. 그런데, 효과는 굉장했다. 이게 선언효과 + 패널티로 돈이 걸림 + 서로의 노력에 대해 격려하고 반응을 남겨줌 의 시너지가 체감이 크게 되었다. 뭐랄까, 4주동안 매일매일 내가 하는 행동을 의식하고 있게 ..
ㅤ 최근에 해결하는데에 꼬박 4일이 걸린 문제가 있었다 ㅜㅜㅜㅜㅜ ㅤ 뷰에서 작은 컴포넌트 위젯에서 GestureDetector를 통해 PanGesture를 인식하고, 터치 좌표값을 받아다가 뷰에게 전달하고, 뷰에서 이를 받아다가 setState로 값을 수정하면 다른 위젯에서 이 값으로 UI를 그리는 로직을 작성하고 있었다. 대충 그림으로 그리면 아래와 같다. ㅤ 이를 위해서 대략적으로 아래 플로우로 실행을 제어하려고 했다. View에서 GestureDetector가 달린 위젯에 콜백함수를 전달 onPanUpdate 시 콜백함수 호출 콜백함수에서 setState 실행 뷰 다시 그리기 position UI 반영 ㅤ 그런데 왠걸? onPanUpdate 함수가 1-2번 호출되고나면 콜백함수가 더 이상 실행되지..
ㅤ 처음에 클린 아키텍처를 프로젝트에 반영하려고 하면서 어떻게 구조를 설계해야하나 고민을 할 때, 아래같은 내용을 담은 적이 있었다. 그리고, 이게 다시 한 번 불편하다고 느낀 상황이 와버렸다! ㅋㅋㅋ ㅤ 아래 이미지처럼 import 문의 크기를 줄이기 위해 열심히 GBDF를 적용해 간소화를 적용하고 있었다. ㅤ 그런데, 저렇게 줄이고 나니깐 각 파일에서 어떤 계층을 참고하고 있는지 더 선명하게 보이기 시작했다. 다시 말하자면, domain 모델에서도 data 계층의 파일들을 import 하여 사용하고 있는게 더 눈에 잘 띄기 시작했다. ㅤ 물론 이게 riverpod 방식으로 파일 구조를 짜려다보니, 앞서 올린 고민 이미지에서 그린 것 처럼 domain에서 data에서 작성한 파일을 필연적으로 impor..
너무나도 객체지향스러운 방식인 오버로딩을 다트 언어에서는 사용할 수가 없었다. 나는 코드를 가독성 넘치면서 깔끔하게 작성하는데에 있어서 오버라이딩, 오버로딩만큼이나 유용한 도구가 없다고 생각했는데, 요런게 제공이 잘 되지 않다보니 좀 불편함을 느끼게 되는 것 같다. ㅤ 아래가 내가 희망하던 코드의 방식이고 // 내가 짜고싶은 코드 List getEntityList({ DateTime bySelectedDate, }) { ... } List getEntityList({ String bySelectedUserId, }) { ... } // -> 이걸 사용하는 시점에는 list = getEntityList(bySelectedDate: DateTime); list = getEntityList(bySelected..
Data Layer 쪽의 리펙토링을 진행하면서, 내가 데이터 계층의 Repository Impl 클래스를 파이어베이스에 의존적이게 코드를 작성하고 있다는 걸 깨달았다. 클린 아키텍처의 의의를 ‘쉽게 갈아끼울 수 있는 백엔드와 프론트엔드’ 라고 생각하고 적용하려고 노력하고 있기 때문에, 범용 클래스를 무조건 “특정 서비스에 의존적이지 않은 형태”로 작성해야 한다고 생각한다. 이에 요걸 분리하기 위해서 여러가지 고민을 했고, 이걸 글로 남겨두려고 한다! ㅤ 현재 계층 구조와 설계한 사용 모델들을 간략하게 써보면 아래와 같다. Presentation Layer에서는 뷰 계층의 model을 사용한다. Domain Layer에서는 Entity를 사용한다. Data Layer에서는 데이터 계층의 model을 사용한..