이번에 야곰 iOS 강의를 들으면서 Array와 ContiguousArray 의 차이에 대해 설명을 들었다. 결론만 요약을 하면 Array는 obj-c 의 NSArray 와 브릿징될 수 있기 때문에, 이에 대비해 준비를 해둔다. ContiguousArray는 브릿징 X → 이를 준비하지 않기에 성능상으로 유리하다. 따라서, 가능한 경우에 ContiguousArray를 사용하는게 좋다! ㅤ 여기 내용을 들으면서 ContiguousArray 라는 것도 처음 알게되었고, objc와 swift 간의 브릿징(형변환)을 염두에 두고 내부적으로 관리를 하고 있다는 것도 처음 알게되었다. 그래서 요런 부분에 대해 조금 더 살펴보고 기록으로 남겨두려고 한다! ㅤ The Swift Array Design 라는 스위프트의 ..
최근에 개발을 공부하면서 ValueObject라는 녀석을 배웠다. 잘만 활용하면 코드를 무척이나 깔끔하게 다듬을 수 있을 것 같아서, 기록으로 남겨두려고 한다. ㅤ Identifier 라는 String을 담는 객체가 있다고 해보자. 여기에서 Idnetifier에는 한글, 영어, 띄어쓰기만 들어갈 수 있다는 규칙이 있다고 가정하자. 만약에 뷰모델에서 가진 함수 중에서 뷰에서 input을 받아와 Identifier 객체를 만들어주는 함수가 있다고 해보자. 그러면 뷰모델은 아래처럼 input 값이 유효한지 검사하고, 유효한 경우에 Identifier 객체를 생성해주어야 한다. ViewModel { func saveIdentifier(input: String) { let pattern = "^[가-힣a-zA-Z..
ㅤ 지금까지는 이미지를 네트워크에서 받아올 때에 FutureBuilder를 통해 에셋이미지를 로드하고, 이를 그려주는 방식으로 적용하고 있었다. 아무래도 Image 위젯 바깥에서 FutureBuilder로 이미지 에셋을 확인하고, 이를 Image 위젯으로 넣어주는 방법이다보니, 이미지와 관련된 로직이 Image 위젯 내에서 딱 처리가 된다는 느낌이 없어서 코드가 지저분하다고 느꼈었다. ㅤ FutureBuilder( // imageFuture가 불러와질 때 까지 아래의 위젯들을 조건에 맞게 보여주기 future: widget.imageFuture, builder: (context, snapshot) { // 데이터를 불러온 경우 if (snapshot.hasData) { return Image(snapsh..
ㅤ 이번에는 또 기묘한 UI를 만났다. ㅤ Flutter의 AppBar는 색상이 반투명한 글래스모피즘처럼 적용되어서, 아래로 스크롤을 올리니 자동으로 색이 반영되는 UI가 기본으로 있었다. 아래 GIF를 확인해보면, 상단 AppBar의 색이 움찔움찔 변경되는 것을 확인할 수 있다. ㅤ 나의 경우에는 바로 아래에 있는 캘린더도 AppBar 쪽에 붙어있기 때문에, 색이 끊겨보여서 이를 제거해주고 싶었다. 그러나, ‘flutter remove appbar background color changed on scroll’ 같은 검색어로 검색했는데, 해결 방법이 잘 나오지 않더라. ㅤ 설마 없겠어? 라고 생각을 하면서 AppBar 위젯의 어트리뷰트를 하나하나 찬찬히 뒤져보면서 해결 방법을 찾았다. AppBar( b..
ㅤ 오늘도 간단한 문제로 3시간을 날렸다. 이전 글에서 SwiftUI의 FullscreenCover 방식의 화면전환을 사용하려면 fullscreenDialog를 사용하면 된다고 했었는데, 여기와 관련된 문제가 발생했다. ㅤ 아래와 같은 구조로 되어있고, 화살표처럼 화면 전환을 만들고자 했다. ㅤ 여기에서, fullscreen dialog로 넘어간 2번째 줄에서는 push로 페이지를 전환한 다음에는 뒤로 pop을 할 수 없는 구조이기에 pushReplacement 같은 함수를 사용해 전환하려고 고려하고 있었다. ㅤ 그러나, fullscreenDialog 첫 페이지에서 pushReplacement 함수를 호출하니, bottomSheet 이 있는 뷰로 가버리는 문제가 있었다! 아마 추측하건데, fullscre..
ㅤ 아래와 같은 화면 전환 기능을 구현하고 싶었다. SwiftUI 에서는 아래 기능을 Fullscreen Cover 라고 부른다. 오른쪽 왼쪽으로 화면이 전환되는 Navigation과 달리 수직으로 올라오는 애니메이션이 특징이며, 모달과 달리 머리를 잡고 아래로 스크롤해도 전환이 취소가 되지 않는다. 주로 일시적인 데이터 입력이나 흐름을 벗어나서 유저가 확 집중을 해야하는 부분에서 이러한 방식을 사용한다. ㅤ ㅤ 뭔가 Navigator.push() 처럼 Navigator 하위에 함수가 있을 것이라고 생각했는데, 찾아보니 없었다. 그래서 아예 모달을 불러오는showBottomModalSheet() 함수처럼 아예 별개의 함수로 있을 거라고 생각해서 구글링을 해봤다. 그런데 띠용? Navigator.push ..
ㅤ 피그마에서 디자인을 하면서, 처음에는 이런 모양의 그래프를 그리고 싶었다. ㅤ 근데, 생각보다 이걸 만드는게 잘 안보이더라. line에서 곡선을 사용해서 만들려고 하니 뭔가 계속 울퉁불퉁한 원이 되어버리고, path를 사용해서 그리자니 더 이상하고. 흠… ㅤ 뭔가 방법이 있을 것 같아서 찾아봤더니, 실제로 있더라! 아래같은 방법으로 진행하면 되는거였다. 나는 몰랐지.. 이리 쉬운건지 ㅋㅋㅋ 작년에도 똑같은 디자인을 했던 적이 있었는데, 한 번 찾아보고 할 걸 그랬다. 작년에는 path 가지고 울퉁불퉁하게 대충 원 따라 만들었던 것 같은데,, ㅤ ellipse 원을 그려준다. ㅤ 오른쪽에 있는 arc를 당겨 원하는 각도를 만들어준다. ㅤ 가운데 ratio를 당겨서 원하는 폭을 만들어준다. ㅤ 각도를 원..
오늘도 쌩고생을 했다. 매주 쌩고생거리가 계속 등장하는 것 같다. ㅜㅜ 심지어 오늘은 다트 문법에 당했다. ㅤ List 뒤에 원소를 추가하고 싶을 때는 append가 아닌 add 함수를 사용해야 한다. 블로그 글을 쓰기 위해서 가져왔는데, 이제야 함수의 차이점이 보인다. ㅤ append 쪽 설명을 읽어보면 “Insert element at the end of the [Iterable]” 이라고 되어있다. 나는 요걸 보고 철썩같이 믿고 썼는데, 아무리 디버깅을 해도 해결이 안돼서 한숨만 푹푹 쉬고 있었지… 근데 요게 문제였을 줄은 몰랐다… 파이어베이스에 복잡하게 쿼리를 날리고 결과를 조인해야 하는 기능이라 중간에 뭐가 잘못되었는지 디버거 켜놓고 값 계속 확인하면서 찾아나섰는데, 제일 마지막에 결과 합쳐서 ..
ㅤ 최근에 해결하는데에 꼬박 4일이 걸린 문제가 있었다 ㅜㅜㅜㅜㅜ ㅤ 뷰에서 작은 컴포넌트 위젯에서 GestureDetector를 통해 PanGesture를 인식하고, 터치 좌표값을 받아다가 뷰에게 전달하고, 뷰에서 이를 받아다가 setState로 값을 수정하면 다른 위젯에서 이 값으로 UI를 그리는 로직을 작성하고 있었다. 대충 그림으로 그리면 아래와 같다. ㅤ 이를 위해서 대략적으로 아래 플로우로 실행을 제어하려고 했다. View에서 GestureDetector가 달린 위젯에 콜백함수를 전달 onPanUpdate 시 콜백함수 호출 콜백함수에서 setState 실행 뷰 다시 그리기 position UI 반영 ㅤ 그런데 왠걸? onPanUpdate 함수가 1-2번 호출되고나면 콜백함수가 더 이상 실행되지..
ㅤ 처음에 클린 아키텍처를 프로젝트에 반영하려고 하면서 어떻게 구조를 설계해야하나 고민을 할 때, 아래같은 내용을 담은 적이 있었다. 그리고, 이게 다시 한 번 불편하다고 느낀 상황이 와버렸다! ㅋㅋㅋ ㅤ 아래 이미지처럼 import 문의 크기를 줄이기 위해 열심히 GBDF를 적용해 간소화를 적용하고 있었다. ㅤ 그런데, 저렇게 줄이고 나니깐 각 파일에서 어떤 계층을 참고하고 있는지 더 선명하게 보이기 시작했다. 다시 말하자면, domain 모델에서도 data 계층의 파일들을 import 하여 사용하고 있는게 더 눈에 잘 띄기 시작했다. ㅤ 물론 이게 riverpod 방식으로 파일 구조를 짜려다보니, 앞서 올린 고민 이미지에서 그린 것 처럼 domain에서 data에서 작성한 파일을 필연적으로 impor..