<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>모바일 개발</title>
    <link>https://mike123789-dev.tistory.com/</link>
    <description>iOS, Flutter &amp;amp; more</description>
    <language>ko</language>
    <pubDate>Mon, 13 Apr 2026 04:39:17 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>mike123789-dev</managingEditor>
    <image>
      <title>모바일 개발</title>
      <url>https://tistory1.daumcdn.net/tistory/4063525/attach/4960c9157e274eb884d6e926729298ed</url>
      <link>https://mike123789-dev.tistory.com</link>
    </image>
    <item>
      <title>플러터 3.10</title>
      <link>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-310</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 3.10이 출시되었으며, 많은 새로운 기능과 개선 사항이 있습니다. 이 포스트에서는 이번 릴리스의 몇 가지 핵심 기능을 살펴보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프레임워크&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Material 3&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Material&lt;/code&gt; 라이브러리가 최신 Material Design 사양과 일치하도록 업데이트되었습니다. 이에는 새로운 구성 요소 및 테마, 업데이트된 시각적 효과 등이 포함됩니다. 개발자는 &lt;b&gt;&lt;code&gt;useMaterial3&lt;/code&gt;&lt;/b&gt; 테마 플래그를 사용하여 이러한 변경 사항에 대해 선택적으로 수용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;code&gt;NavigationBar&lt;/code&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;및&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;code&gt;NavigationDrawer&lt;/code&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;위젯이 Material 3 디자인과 일치하도록 업데이트되었습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;code&gt;SearchBar&lt;/code&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;및&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;code&gt;SearchAnchor&lt;/code&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;구성 요소는 검색 쿼리에 대한 예측 텍스트를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vuDlj/btsfaKQBfYX/wKssHtayvjkMKHWiw2UeoK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vuDlj/btsfaKQBfYX/wKssHtayvjkMKHWiw2UeoK/img.gif&quot; data-alt=&quot;NavigationBar&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vuDlj/btsfaKQBfYX/wKssHtayvjkMKHWiw2UeoK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/vuDlj/btsfaKQBfYX/wKssHtayvjkMKHWiw2UeoK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;114&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;114&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NavigationBar&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2l4Nw/btsfeAe1Ea5/aFRyXxCFM1lmF5GFgyI2N1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2l4Nw/btsfeAe1Ea5/aFRyXxCFM1lmF5GFgyI2N1/img.gif&quot; data-alt=&quot;NavigationDrawer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2l4Nw/btsfeAe1Ea5/aFRyXxCFM1lmF5GFgyI2N1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b2l4Nw/btsfeAe1Ea5/aFRyXxCFM1lmF5GFgyI2N1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;350&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NavigationDrawer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEcmU8/btsfg3HLn7m/binzS7UW42aUgKFha5lJb0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEcmU8/btsfg3HLn7m/binzS7UW42aUgKFha5lJb0/img.gif&quot; data-alt=&quot;SearchBar and SearchAnchor&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEcmU8/btsfg3HLn7m/binzS7UW42aUgKFha5lJb0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dEcmU8/btsfg3HLn7m/binzS7UW42aUgKFha5lJb0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;470&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SearchBar and SearchAnchor&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Material 3에 맞춰 &lt;b&gt;&lt;code&gt;DatePicker&lt;/code&gt;&lt;/b&gt; 및 &lt;b&gt;&lt;code&gt;TimePicker&lt;/code&gt;&lt;/b&gt;가 새로운 색상, 레이아웃 및 모양으로 업데이트되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTbTNh/btsfbzOPukh/rSdQBxtTcvVk6DRVzYx110/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTbTNh/btsfbzOPukh/rSdQBxtTcvVk6DRVzYx110/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTbTNh/btsfbzOPukh/rSdQBxtTcvVk6DRVzYx110/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bTbTNh/btsfbzOPukh/rSdQBxtTcvVk6DRVzYx110/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;338&quot; height=&quot;512&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCiP2p/btsfclbSdRb/iQZCXaGaIF9sSW3PGXSMn1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCiP2p/btsfclbSdRb/iQZCXaGaIF9sSW3PGXSMn1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCiP2p/btsfclbSdRb/iQZCXaGaIF9sSW3PGXSMn1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cCiP2p/btsfclbSdRb/iQZCXaGaIF9sSW3PGXSMn1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;363&quot; height=&quot;512&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Material 3에 맞춰&lt;span&gt;&lt;b&gt; ListTile&lt;/b&gt;과&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;및&lt;span&gt;&lt;b&gt; BottomSheet&lt;/b&gt;도 업데이트 되었습니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V1sPo/btsfaavgTOY/wBwIdJbI6rIfAn4nZEoSZ0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V1sPo/btsfaavgTOY/wBwIdJbI6rIfAn4nZEoSZ0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V1sPo/btsfaavgTOY/wBwIdJbI6rIfAn4nZEoSZ0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/V1sPo/btsfaavgTOY/wBwIdJbI6rIfAn4nZEoSZ0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;197&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dA4zmG/btsfeATEbUo/JQDxngDpbwsYX4vkOwH2A1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dA4zmG/btsfeATEbUo/JQDxngDpbwsYX4vkOwH2A1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dA4zmG/btsfeATEbUo/JQDxngDpbwsYX4vkOwH2A1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dA4zmG/btsfeATEbUo/JQDxngDpbwsYX4vkOwH2A1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;470&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://flutter.github.io/samples/material_3.html&quot;&gt;demo app&lt;/a&gt;&amp;nbsp;에서 확인 가능합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Mobile&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;iOS&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Impeller&lt;/b&gt;가 이제 iOS의 기본 렌더러이며, 성능이 개선되었으며 더 이상 지연 현상이 발생하지 않습니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;iOS 기기용 무선 디버깅이 이제 가능합니다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;SpellCheckConfiguration() 위젯은 이제 iOS에서 Apple의 맞춤법 검사 서비스를 기본으로 지원합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Impeller 엔진이란?&lt;br /&gt;Impeller는 Flutter를 위한 새로운 렌더링 런타임으로, 이전의 &lt;b&gt;Skia 코드를 대체하여&lt;/b&gt; 모던 하드웨어 가속화 그래픽 API (iOS의 Metal 및 Android의 Vulkan)를 완전히 활용하는 맞춤형 런타임입니다. Flutter 팀은 Impeller가 엔진 빌드 시간에 더 작고 간단한 셰이더 집합을 미리 컴파일하기 때문에 런타임에서 컴파일하지 않아 Flutter의 초반 지연 문제를 해결한다고 믿습니다. Impeller에는 예측 가능한 성능, 계기 가능성, 이식성, 모던 그래픽 API 및 동시성을 활용하는 등의 목표가 있습니다. Impeller는 iOS에서 기본적으로 활성화되며 성능이 향상되고 지연이 적어집니다&lt;br /&gt;&lt;br /&gt;참고: https://docs.flutter.dev/perf/impeller&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Android&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack 라이브러리인 Camera X가 Flutter Camera 플러그인에서 Android를 지원합니다. 개발자는 Android 앱에 풍부한 카메라 기능을 쉽게 추가할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;보안&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 프레임워크는 이제 SLSA (소프트웨어 아티팩트 공급망 수준) 1 수준으로 컴파일됩니다. 이를 통해 스크립트 빌드 프로세스, 감사 로깅과 함께 다중 승인 기능 등을 구현하여 보안을 강화합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Web&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이콘 폰트의 파일 크기가 줄어듦으로써 Flutter &lt;b&gt;웹 앱의 로드 시간이 개선&lt;/b&gt;되었습니다. 모든 브라우저에서 &lt;b&gt;CanvasKit도 크기가 줄어&lt;/b&gt;들었습니다. 요소 포함이 이제 가능하며, Flutter 웹 앱을 페이지의 특정 요소에서 제공할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DevTools&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevTools는 Material 3를 사용하는 새로운 UI와 개선된 기능으로 업데이트되었습니다. 콘솔은 이제 디버그 모드에서 실행 중인 앱에 대한 평가를 지원합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/flutter/whats-new-in-flutter-3-10-b21db2c38c73&quot;&gt;What&amp;rsquo;s new in Flutter 3.10. Seamless web and mobile integration&amp;hellip; | by Kevin Chisholm | Flutter | May, 2023 | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.flutter.dev/release/release-notes/release-notes-3.10.0&quot;&gt;Flutter 3.10.0 release notes | Flutter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Flutter</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/31</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-310#entry31comment</comments>
      <pubDate>Sat, 13 May 2023 13:09:41 +0900</pubDate>
    </item>
    <item>
      <title>Flutter와 Material 3</title>
      <link>https://mike123789-dev.tistory.com/entry/Flutter%EC%99%80-Material-3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;구글에서 제공하는 오픈소스 프레임워크인 &lt;b&gt;Flutter&lt;/b&gt;는 하나의 코드베이스에서 멀티 플랫폼 애플리케이션을 아름답게 네이티브로 컴파일할 수 있습니다. Flutter의 주요 기능 중 하나는 Material Design을 사용하여 아름답고 반응형 사용자 인터페이스를 만드는 능력입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Material Design&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Material Design&lt;/b&gt;은 구글 디자이너와 개발자들이 만들고 지원하는 오픈소스 디자인 시스템입니다. 최신 버전인 &lt;b&gt;Material 3&lt;/b&gt;은 동적인 색상, 향상된 접근성, 대형 스크린 레이아웃을 위한 기초, 디자인 토큰 등을 통해 개인화 가능하고 표현력 있는 경험을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Material 3은&lt;/b&gt; TextButton.icon, OutlinedButton.icon, ElevatedButton.icon과 같은 새로운 위젯을 제공하여 개발자들이 쉽게 아이콘을 추가할 수 있습니다. 또한, Material Design 3은 새로운 색상 스키마와 타이포그래피 옵션을 소개하며, 애플리케이션의 브랜드 아이덴티티에 맞게 사용자 정의할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Material Design 2와 Material Design 3의 주요 차이점은 &lt;b&gt;개인화와 사용자 표현에&lt;/b&gt; 대한 초점입니다. Material Design 3은 사용자 선호도에 따라 라이트 모드와 다크 모드를 전환할 수 있는 기능을 포함하여 개인화에 더 많은 옵션을 제공합니다. 또한, Material Design 3은 더 많은 유연성을 제공하는 디자인 토큰을 새롭게 소개합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Flutter에서 사용하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter에서 지원되는 &lt;b&gt;Material Design 3&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://m3.material.io/develop/flutter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://m3.material.io/develop/flutter &lt;/a&gt;에서 확인 가능합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹에서 직접 사용가능한 &lt;a title=&quot;material_3_demo&quot; href=&quot;https://flutter.github.io/samples/web/material_3_demo/#/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;material_3_demo&lt;/a&gt;&amp;nbsp;사이트도 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter를 사용하면 앱에서 Material Design을 쉽게 구현할 수 있습니다. 다양한 내장형 Material 위젯으로 아름답고 반응형 사용자 인터페이스를 쉽게 만들 수 있는데요. 예를 들어, &lt;code&gt;Scaffold&lt;/code&gt; 위젯을 사용하여 앱 바, 본문 및 부동 액션 버튼을 포함한 기본적인 Material Design 앱 구조를 만들 수 있습니다. &lt;code&gt;AppBar&lt;/code&gt; 위젯을 사용하여 내비게이션과 작업이 포함된 상단 앱 바를 만들 수 있으며, &lt;code&gt;FloatingActionButton&lt;/code&gt; 위젯을 사용하여 앱에서 주요 작업을 수행하는 부동 액션 버튼을 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;code&gt;TextField&lt;/code&gt;, &lt;code&gt;Button&lt;/code&gt;, &lt;code&gt;Card&lt;/code&gt;, &lt;code&gt;ListTile&lt;/code&gt; 등의 Material Design 구성 요소를 사용하여 아름답고 반응형 사용자 인터페이스를 만들 수 있습니다. 이러한 구성 요소는 Material Design 가이드라인을 따르도록 설계되어 앱 전체에서 일관된 모습과 느낌을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter의 Material Design을 사용하여 아름답고 반응형 사용자 인터페이스를 만들 수 있으므로 사용자를 기쁘게 만드는 멋진 앱을 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/30</guid>
      <comments>https://mike123789-dev.tistory.com/entry/Flutter%EC%99%80-Material-3#entry30comment</comments>
      <pubDate>Sat, 8 Apr 2023 14:09:12 +0900</pubDate>
    </item>
    <item>
      <title>함수형 프로그래밍에 대하여(feat. Swift)</title>
      <link>https://mike123789-dev.tistory.com/entry/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%97%90-%EB%8C%80%ED%95%98%EC%97%ACfeat-Swift</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;현재 프로젝트서 &lt;a href=&quot;https://github.com/pointfreeco/swift-composable-architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The Composable Architecture&lt;/a&gt;를 사용하고 있습니다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;라이브러리를 만든 개발자는 함수형 프로그래밍을 고려하며 만들었다고 해서, &lt;b&gt;함수형 프로그래밍&lt;/b&gt;에 대해서 알아보려합니다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;워낙에 생소한 개념이다 보니까, 엄청나게 자세한 설명과 예제보다는&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;함수형 프로그래밍 (Functional Programming)을 이해하는데 필요한 기본 용어와 개념을 중심적으로 정리해봤습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;사이드 이펙트(Side Effect)란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 함수를 호출했을 때, 그 함수의 반환값 이외에 호출된 함수 밖에서 프로그램의 상태변화가 발생하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 Side Effect라합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저렇게 쓰니까 전혀 와닿지 않네요&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;내가 어떻게 컨트롤 할 수 없는 외부의 세계에 접근한다&quot;라는 생각이 들면&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Side Effect라고 봐도 될 것 같아요.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가장 대표적으로는 File I/O, 네트워킹, 콘솔 로깅,&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;순수 함수(Pure Function)란?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 input에 대해서 항상 동일한 output을 반환하는 함수&lt;/li&gt;
&lt;li&gt;그리고 함수 외부의 값을 사용하지 않아 사이드 이펙트가 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 순수 함수가 가지는 장점이 뭘까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;테스팅하기 좋습니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;output(결과)가 오직 input에만 의존적이기 때문에 테스트 코드를 짜는 게 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통적으로 접근해야 하는 상태가 없기 때문에 &lt;b&gt;parallel하게 프로그램을 실행할 수 있습니다&lt;/b&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;...그런데?&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우리가 만들고 싶은 앱이 이러한 SideEffect가 없으면 과연 얼마나 의미가 있을까요?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 네트워킹, IO와 같은 것을 어떻게 다루는지가 중요합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;함수형 프로그래밍(Functional Programming)은 side effect를 하지 말자! 가 아닙니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;side effect를 어떻게 잘 관리해서 우리의 코드를 테스트하기 좋은 구조로, compose 하기 좋은 구조로 짤 수 있을까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;고민해야 합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그래서, &quot;나는 이러한 input이 있고, 이러한 output을 원한다&quot;를 생각하고,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드를 작은 함수로 쪼갠다음에, 필요한 함수들을 연결하는 것이 목표가 됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다시&amp;nbsp;&lt;a href=&quot;https://github.com/pointfreeco/swift-composable-architecture&quot;&gt;The Composable Architecture&lt;/a&gt;로 돌아오면...&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 Github에서 Composable Architecture에 대한 설명을 보면...&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;Composition&lt;/b&gt;&lt;br /&gt;How to break down large features into smaller components that can be extracted to their own, isolated modules and be easily glued back together to form the feature.&lt;br /&gt;&lt;b&gt;Side effects&lt;/b&gt;&lt;br /&gt;How to let certain parts of the application talk to the outside world in the most testable and understandable way possible.&lt;br /&gt;&lt;b&gt;Testing&lt;/b&gt;&lt;br /&gt;How to not only test a feature built in the architecture, but also write integration tests for features that have been composed of many parts, and write end-to-end tests to understand how side effects influence your application.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확실히 Fucntional Programming에서 추구하는 방향과 겹치네요&lt;/p&gt;</description>
      <category>개발</category>
      <category>functional programming</category>
      <category>Swift</category>
      <category>함수형 프로그래밍</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/29</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%97%90-%EB%8C%80%ED%95%98%EC%97%ACfeat-Swift#entry29comment</comments>
      <pubDate>Mon, 4 Oct 2021 13:54:26 +0900</pubDate>
    </item>
    <item>
      <title>SwiftUI 커스텀 컨테이너 뷰 만들기</title>
      <link>https://mike123789-dev.tistory.com/entry/SwiftUI-%EC%BB%A4%EC%8A%A4%ED%85%80-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%B7%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 &lt;b&gt;컨테이너 뷰&lt;/b&gt;가 뭘까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple 문서를 인용하자면...&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;SwiftUI provides a range of container views that group and repeat views. Use some containers purely for structure and layout, like stack views, lazy stack views, and grid views. Use others, like lists and forms, to also adopt system-standard visuals and interactivity&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말 그대로 View를 Contain 하는 View를 컨테이너 뷰라고 하겠습니다. 가장 대표적으로 VStack, HStack 등이 있겠네요. 하지만 애플에서 기본적으로 제공되는 뷰 만으로는 한계가 있을 때가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 예시를 드는게 제일 좋겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 뷰를 카드뷰를 만들어야 한다고 가정해볼게요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;214&quot; data-origin-height=&quot;178&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ocSQt/btrfWbGzyp9/w0NaMvEejD0X8TJOWFRSsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ocSQt/btrfWbGzyp9/w0NaMvEejD0X8TJOWFRSsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ocSQt/btrfWbGzyp9/w0NaMvEejD0X8TJOWFRSsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FocSQt%2FbtrfWbGzyp9%2Fw0NaMvEejD0X8TJOWFRSsK%2Fimg.png&quot; data-origin-width=&quot;214&quot; data-origin-height=&quot;178&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 생각나는 방법은&lt;/p&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;struct NaiveCardView: View {
    let title: String
    var body: some View {
        Text(title)
            .padding()
            .background(Color.white)
            .cornerRadius(10)
            .shadow(radius: 5)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일것 같네요&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;PS. &lt;i&gt;UIKit이랑 비교하면 훨 편하죠...&lt;/i&gt;.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 카드뷰가 &lt;code&gt;Text&lt;/code&gt;만 감싸는 거면 상관없겠지만 &lt;code&gt;Text&lt;/code&gt;가 아닌 &lt;code&gt;Label&lt;/code&gt;이나 &lt;code&gt;Image&lt;/code&gt;를 감싸야한다면?&lt;br /&gt;그때마다 CardTextView, CardLabelView를 따로 만드는 건 비효율적이겠죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 어떠한 View든 받을 수 있도록 제너릭으로 바꿔줄게요&lt;/p&gt;
&lt;pre class=&quot;swift&quot; data-ke-language=&quot;swift&quot;&gt;&lt;code&gt;struct GenericCardView&amp;lt;Content: View&amp;gt;: View {
    var content: () -&amp;gt; Content
    var body: some View {
        Group(content: content)
            .padding()
            .background(Color.white)
            .cornerRadius(10)
            .shadow(radius: 5)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 마치 Text를 VStack으로 감싸듯 GenericCardView로 감싸주면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;GenericCardView {
    Text(&quot;Hello&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이제는 Text 외에도 다른 View도 이용할 수 있습니다&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;GenericCardView {
    Image(systemName: &quot;star&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;196&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNzzBh/btrf1ikoo1p/IsBfCktrKWa4t9JeVkFjc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNzzBh/btrf1ikoo1p/IsBfCktrKWa4t9JeVkFjc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNzzBh/btrf1ikoo1p/IsBfCktrKWa4t9JeVkFjc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNzzBh%2Fbtrf1ikoo1p%2FIsBfCktrKWa4t9JeVkFjc0%2Fimg.png&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;196&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이것도 한계가 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;254&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TF0Ds/btrf5h6lqH2/kwPSQdyjaMMHugYXEMRfB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TF0Ds/btrf5h6lqH2/kwPSQdyjaMMHugYXEMRfB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TF0Ds/btrf5h6lqH2/kwPSQdyjaMMHugYXEMRfB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTF0Ds%2Fbtrf5h6lqH2%2FkwPSQdyjaMMHugYXEMRfB1%2Fimg.png&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;254&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View를 한계 이상 넘겨주려 하면 컴파일이 안됩니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 View들을 다 Group로 감싸주면 해결은 되지만... 매번 감싸주는 게 그닥 좋은 방법은 아닌 것 같네요&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;GenericCardView {
    Group {
        Text(&quot;Hello&quot;)
        Image(systemName: &quot;star&quot;)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다행히도 매우 간단한 해결법이 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;content 클로저를 @ViewBuilder 로 annotate해 주면 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;잠깐?! ViewBuilder가 뭘까요?&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;애플이 SwiftUI를 공개하던 시점에 Swift에도 변화가 생겼는데 result builders 라는 개념이 생겼습니다.&lt;br /&gt;이러한 result builder중에 View에 특화된 친구가 ViewBuilder입니다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 친구가 어떤 일을 하는지 코드를 살짝 엿보면...&lt;/p&gt;
&lt;pre class=&quot;swift&quot;&gt;&lt;code&gt;@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension ViewBuilder {
    public static func buildBlock&amp;lt;C0, C1&amp;gt;(_ c0: C0, _ c1: C1) -&amp;gt; TupleView&amp;lt;(C0, C1)&amp;gt; where C0 : View, C1 : View
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한개 이상의 View를 받아서 하나의 TupleView로 반환해주고 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;결과적으로는 여러 뷰를 하나의 뷰로 묶어주는 역할을 한다고 보면 될 것 같습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;자세한 얘기는 아래 링크를 확인하시면 될 것 같습니다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md&quot;&gt;https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로는 init 단계에서 @ViewBuilder annotaion을 추가해주면 됩니다!&lt;/p&gt;
&lt;pre class=&quot;swift&quot; data-ke-language=&quot;swift&quot;&gt;&lt;code&gt;struct GenericCardView&amp;lt;Content: View&amp;gt;: View {
    var content: () -&amp;gt; Content

    init(@ViewBuilder content: @escaping () -&amp;gt; Content) {
        self.content = content
    }

    var body: some View {
        Group(content: content)
            .padding()
            .background(Color.white)
            .cornerRadius(10)
            .shadow(radius: 5)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PS.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만... 카드 뷰를 만드는 방법이 이것 하나뿐일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금 만든 카드뷰를 한번 다시 살펴보면&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.padding()
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 뷰 모디파이어를 합친 게 다입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 &lt;b&gt;굳이 뷰를 만들지 않고 커스텀 뷰 모디파이어를 만들어도 되지 않을까요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 건 다음 글에....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.swiftbysundell.com/tips/creating-custom-swiftui-container-views/&quot;&gt;https://www.swiftbysundell.com/tips/creating-custom-swiftui-container-views/&lt;/a&gt;&lt;/p&gt;</description>
      <category> /SwiftUI</category>
      <category>ios</category>
      <category>MacOS</category>
      <category>Swift</category>
      <category>SwiftUI</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/28</guid>
      <comments>https://mike123789-dev.tistory.com/entry/SwiftUI-%EC%BB%A4%EC%8A%A4%ED%85%80-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%B7%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0#entry28comment</comments>
      <pubDate>Sun, 26 Sep 2021 15:19:05 +0900</pubDate>
    </item>
    <item>
      <title>지극히 주관적으로 해석한 코딩 명언</title>
      <link>https://mike123789-dev.tistory.com/entry/%EC%A7%80%EA%B7%B9%ED%9E%88-%EC%A3%BC%EA%B4%80%EC%A0%81%EC%9C%BC%EB%A1%9C-%ED%95%B4%EC%84%9D%ED%95%9C-%EC%BD%94%EB%94%A9-%EB%AA%85%EC%96%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 학생일 때는 코드가 내 뜻대로 실행되는 것에만 만족을 했었는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀으로 일을 해야하는 개발자로 생활하다 보니 코드 한 줄 한 줄 추가하는데 더 많은 생각을 하게 되네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나만의 &lt;b&gt;코딩 철학&lt;/b&gt;을 가지고 싶어서 코딩 관련 글들을 읽다가 마음에 드는 명언(?)을 모아봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;Any fool can write code that a computer can understand. Good programmers write code that humans can understand.&quot;&lt;br /&gt;- Martin Fowler&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 &lt;a href=&quot;https://martinfowler.com/books/refactoring.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;리팩토링&lt;/a&gt;의 저자인 마틴 파울러가 한 말입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇십 년 전까지는 컴퓨터의 입장에서 &quot;어떻게 하면 조금이라도 더 최적화할 수 있을까?&quot;를 생각하는 게 맞았겠지만.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터/스마트폰의 성능이 기하급수적으로 좋아진 현재에서는 오버킬입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;좋은 코드는 사람이 이해하기 좋은 코드다&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 붙이자면 &quot;&lt;b&gt;다른&lt;/b&gt;&quot; &lt;b&gt;사람도&lt;/b&gt; 이해하기 좋은 코드 일 것 같네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 혼자서 개발하는 개발자는 없을것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항상 다른 개발자가 언제든 내 코드를 볼 수 있다 라는 생각을 가지고 코드를 짜야겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 다른 사람의 입장에서 코드를 짜야하면 조금 막연할 때가 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 그럴때에는 &quot;이 코드를 반년 후에도 이해할 수 있을까?&quot;라고 생각하며 코드를 짭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;nbsp;&quot;&lt;b&gt;Simplicity&lt;/b&gt; is prerequisite for reliability.&quot;&lt;br /&gt;- Edsger W. Dijkstra&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;ldquo;The best code is &lt;b&gt;no code&lt;/b&gt; at all. Every new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported. Every time you write new code, you should do so reluctantly, under duress, because you completely exhausted all your other options.&amp;rdquo;&lt;br /&gt;- Jeff Atwood&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;The fastest code is the code which does not run. The code easiest to maintain is the code that was &lt;b&gt;never written&lt;/b&gt;.&amp;rdquo;&lt;br /&gt;- Robert Galanakis&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩 관련된 명언에서 정말 자주 얘기가 나오는 것들을 모아봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 코드는 &lt;b&gt;최소한일 수록 좋다&lt;/b&gt; 라는 것을 전하려고 하는 말들이네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에는 코드의 line 수가 많으면 잘 짠 거라고 착각을 했는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 같은 일을 하는데 더 간결한 코드가 더 좋은 코드라고 생각을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(그리고 가독성도 좋아지기 때문에 자연스럽게 이애하기 쉬운 코드가 되는 것 같아요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Everything should be made as simple as possible, but not simpler&lt;br /&gt;- Einstein&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 그렇다고 기괴할 정도로 짧은 코드가 좋은 거는 아니겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;Give a man a program, frustrate him for a day.&lt;br /&gt;Teach a man to program, frustrate him for a lifetime.&quot;&lt;br /&gt;- Muhammad Waseem&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거는 약간 자조적인 얘기인것 같네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩을 하는것이 직업인 사람한테 코딩으로 인한 스트레스틑 숙명으로 받아들이는 게 좋을 것 같습니다. ㅋㅋㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;글을 마치며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론.... 코드를 짤때&amp;nbsp;&lt;b&gt;정답&lt;/b&gt;은 없는것 같네요 (물론 오답은 있는 것 같지만...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 주어진 상황에 따라서 임해야 하는 자세도 달리지겠죠...?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 데드라인이 얼마 안 남아서 시간이 없는데 코드를 처음부터 클린 하게 짜는 것이 가능할까요?&lt;br /&gt;어쩌면 먼저 짠 후다닥 짠 다음에 나중에 숨좀 돌리고 리팩터링을 하는 것이 더 좋을 수도 있습니다.&lt;/li&gt;
&lt;li&gt;어떤 코드를 짜는데, A와 B가 있다고 가정해볼게요. (A, B 둘 다 성능상으로는 동일)&lt;br /&gt;개인적으로는 A가 좋아 보이지만, 팀에서는 B로 하기로 약속을 했으면 통일성을 위해서 B로 하는 게 맞을 것 같네요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 상황에서 최선의 코드를 짤 수 있도록 노력해야겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 고민이 있을 때는 주변을 둘러보는 것도 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주변에 고민을 같이 들어줄 동료/친구가 있다면 함께 의견을 나누고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 당장 옆에 사람이 없다면,&amp;nbsp;구글링을 하는 것도 좋은 방법이고, 오픈소스 코드를 참고하는 것도 큰 도움이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글을 너무 두서없이 써서 어떻게 마무리할지 잘 모르겠네요  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확실한 거는 앞으로 코드를 짤 때 하나의 생각을 뇌 뒤편에 심어둘 것 같습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어떻게 하면 코드를 조금만 짤 수 있을까? 이 코드를 반년 후에 이해할 수 있을까?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌 게이츠의 말을 인용하면서 마무리하겠습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;ldquo;I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.&amp;rdquo;&lt;br /&gt;- Bill Gates&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발</category>
      <category>개발</category>
      <category>개발자</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/27</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%EC%A7%80%EA%B7%B9%ED%9E%88-%EC%A3%BC%EA%B4%80%EC%A0%81%EC%9C%BC%EB%A1%9C-%ED%95%B4%EC%84%9D%ED%95%9C-%EC%BD%94%EB%94%A9-%EB%AA%85%EC%96%B8#entry27comment</comments>
      <pubDate>Fri, 24 Sep 2021 21:22:37 +0900</pubDate>
    </item>
    <item>
      <title>개발자로 구글링하는 법</title>
      <link>https://mike123789-dev.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A1%9C-%EA%B5%AC%EA%B8%80%EB%A7%81%ED%95%98%EB%8A%94-%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터 공학 전공 학생이라면, 혹은 매일 코드를 짜는 개발자라면 구글링은 필수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;짧은 시간 내에 원하는 정보를 정확하게 찾아내는게 점점 중요해 진것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 오늘은 구글링을 할때 도움이 되는 팁 몇가지를 공유합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;키워드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;긴 검색어 중 꼭 포함해야하는 키워드가 있으면 &lt;code&gt;&quot;&quot;&lt;/code&gt;로 감싸주세요&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;how to make shadow &quot;uikit&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;그리고 키워드를 제외하고 싶다면 해당 키워드 앞에 &lt;code&gt;-&lt;/code&gt; 를 붙여주세요&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;how to make shadow &quot;uikit&quot; -swiftui&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사이트&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 사이트 내에서 검색하고 싶다면 해당 사이트 URL 앞에 &lt;code&gt;site:&lt;/code&gt; 를 붙여주세요PS. 애플의 공식문서를 검색하고 싶을때 site:apple.com 을 자주 사용했습니다&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;site:apple.com circle swift&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;615&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbjSqz/btrfsdEnqT1/1KHL2fOGJFQax6LWQnFRE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbjSqz/btrfsdEnqT1/1KHL2fOGJFQax6LWQnFRE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbjSqz/btrfsdEnqT1/1KHL2fOGJFQax6LWQnFRE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbjSqz%2FbtrfsdEnqT1%2F1KHL2fOGJFQax6LWQnFRE0%2Fimg.png&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;615&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;날짜&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 날짜 이전 혹은 이후을 제한해서 검색을 하고싶다면 &lt;code&gt;after&lt;/code&gt; , &lt;code&gt;before&lt;/code&gt;를 붙여주세요PS. 어떤 프레임워크의 API가 deprecate 되기 이전의 검색을 하고 싶을때 유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;swiftui textfield before:2021&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;how to move file in swift after:2018&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;와일드 카드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검생을 할때 비워주고 싶은 부분은 &lt;code&gt;*&lt;/code&gt; 을 끼워주면됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;how to build a * with swift&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;파일 타입&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 타입을 지정하는것도 가능합니다.&lt;/li&gt;
&lt;li&gt;저는 PDF 파일을 찾을때, 혹은 이미지 중 gif만 찾고 싶을때 자주 사용했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;Foobar filetype:pdf&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;loading filetype:gif&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1011&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbg1gT/btrftnNwUSf/vzEtlBBCESJiAjMRflItV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbg1gT/btrftnNwUSf/vzEtlBBCESJiAjMRflItV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbg1gT/btrftnNwUSf/vzEtlBBCESJiAjMRflItV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbg1gT%2FbtrftnNwUSf%2FvzEtlBBCESJiAjMRflItV0%2Fimg.png&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1011&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;꼭 구글을 이용해야할까...?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;99%의 경우에는 검색 결과에 만족을 하겠지만, 가아아아끔 원하는 결과가 안 나오는경우도 있을 수 있죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글외에 사용 하는 검색 엔진인 &lt;a href=&quot;https://duckduckgo.com&quot;&gt;DuckDuckGo&lt;/a&gt; 도 추천합니다&lt;/p&gt;</description>
      <category>개발</category>
      <category>ios</category>
      <category>개발자</category>
      <category>구글링</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/26</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A1%9C-%EA%B5%AC%EA%B8%80%EB%A7%81%ED%95%98%EB%8A%94-%EB%B2%95#entry26comment</comments>
      <pubDate>Sun, 19 Sep 2021 20:42:08 +0900</pubDate>
    </item>
    <item>
      <title>[플러터 2.0] 버튼 - (2) (ToggleButtons, DropdownButton, PopupMenuButton)</title>
      <link>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-%EB%B2%84%ED%8A%BC-2-ToggleButtons-DropdownButton-PopupMenuButton</link>
      <description>&lt;p&gt;이전 글에서는 TextButton, ElevatedButton, OutlinedButton 즉 하나의 버튼 만을 알아봤습니다.&lt;/p&gt;
&lt;p&gt;그런데 하나의 버튼이 아닌 여러 개의 버튼이 필요할 때가 있겠죠?&lt;/p&gt;
&lt;p&gt;가장 많이 쓰이는것은 ToggleButtons, DropdownButton, PopupMenuButton입니다&lt;br /&gt;각 버튼들이 어떻게 다른지 그리고 어떤 상황에서 쓰이는지 한번 알아볼게요&lt;/p&gt;
&lt;p&gt;역시나 글로 설명하는것 보다는 직접 실험을 할 수 있도록 dartpad를 준비했습니다.&lt;/p&gt;
&lt;iframe style=&quot;width:900px;height:600px;&quot; src=&quot;https://dartpad.dev/embed-flutter.html?id=be29bf6ce071c3b622c44b1c784ba60e&amp;run=true&amp;split=50&quot;&gt;&lt;/iframe&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;ToggleButtons class&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;385&quot; width=&quot;531&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi0Gs8/btq2MuTwCrW/mEZtIxVVs6ODaoblGGrMX1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi0Gs8/btq2MuTwCrW/mEZtIxVVs6ODaoblGGrMX1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi0Gs8/btq2MuTwCrW/mEZtIxVVs6ODaoblGGrMX1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bi0Gs8/btq2MuTwCrW/mEZtIxVVs6ODaoblGGrMX1/img.gif&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;385&quot; width=&quot;531&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ToggleButtons는 child 버튼들이 row로 표시됩니다. 각 버튼의 state는 &lt;code&gt;isSelected&lt;/code&gt;로 결정이 됩니다.&lt;/p&gt;
&lt;p&gt;그래서 버튼들의 &lt;b&gt;개수에 맞게&lt;/b&gt; bool 리스트를 넘겨줘야합니다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;ToggleButtons(
    children: &amp;lt;Widget&amp;gt;[
      Icon(Icons.ac_unit),
      Icon(Icons.call),
      Text(&quot;WIFI&quot;),
    ],
    onPressed: (int index) {
      setState(() {
        _selections1[index] = !_selections1[index];
      });
    },
    isSelected: _selections1,
  ),&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;기본적으로 제공되는 ToggleButtons은 row로 밖에 못 쓰지만 RotatedBox를 쓰면 약간의 꼼수(?)로 column처럼 보이게 할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;RotatedBox(
quarterTurns: 1,
  child: ToggleButtons(
    color: Colors.greenAccent,
    children: &amp;lt;Widget&amp;gt;[
             RotatedBox(quarterTurns: 3, child: Icon(Icons.format_bold)),
             RotatedBox(quarterTurns: 3, child: Icon(Icons.format_italic)),
             RotatedBox(quarterTurns: 3, child: Icon(Icons.link)),
        ],
    isSelected: isSelected,
  ),
)&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;DropdownButton class&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;370&quot; data-filename=&quot;ezgif.com-gif-maker_(1).gif&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eE5nme/btq2SLy35zM/RKCkhBueEFaaffamVg9RGk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eE5nme/btq2SLy35zM/RKCkhBueEFaaffamVg9RGk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eE5nme/btq2SLy35zM/RKCkhBueEFaaffamVg9RGk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/eE5nme/btq2SLy35zM/RKCkhBueEFaaffamVg9RGk/img.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;370&quot; data-filename=&quot;ezgif.com-gif-maker_(1).gif&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;DropdownButton은 list의 버튼들 중에서 선택할 때 쓰입니다. DropdownButton은 현재 선택된 item을 보여주면, 버튼을 누를 때 선택할 수 있는 item들을 보여줍니다.&lt;/p&gt;
&lt;p&gt;타입 T는 각 dropdown item의 value를 의미합니다. Dropdown의 list의 버튼은 무조건 해당 T의 value 이 여아 합니다. 일반적으로 enum이 이용됩니다.&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;enum MenuType { first, second, third }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;onChanged 콜백은&lt;/b&gt; 선택한 dropdown value를 업데이트합니다. 일반적으로 setState를 호출해서 새롭게 선택된 value로 업데이트합니다.&lt;/p&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;DropdownButton(
    value: _dropdownValue,
    items: MenuType.values
        .map((value) =&amp;gt; DropdownMenuItem(
              value: value,
              child: Text(value.toShortString()),
            ))
        .toList(),
    onChanged: (newValue) {
      setState(() {
        _dropdownValue = newValue;
      });
    },
    elevation: 4,
  )&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;PopupMenuButton class&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;ezgif.com-gif-maker_(3).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;370&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNOOBO/btq2N1o77Jw/4A0OlkR1MVaZlcUhjJKxa1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNOOBO/btq2N1o77Jw/4A0OlkR1MVaZlcUhjJKxa1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNOOBO/btq2N1o77Jw/4A0OlkR1MVaZlcUhjJKxa1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bNOOBO/btq2N1o77Jw/4A0OlkR1MVaZlcUhjJKxa1/img.gif&quot; data-filename=&quot;ezgif.com-gif-maker_(3).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;370&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;앞서 설명한 DropdownButton와 비슷한데, item을 선택했을대 menu는 dismiss가 됩니다. 즉 현재 선택한 item이 표시되지 않는 점이 Dropdown Button과 PopupMenuButton의 차이점이 되겠네요.&lt;/p&gt;
&lt;p&gt;PopupMenuButton에 icon이 제공되는 경우 IconButton처럼 행동하게 됩니다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;PopupMenuButton&amp;lt;MenuType&amp;gt;(
  icon: Icon(Icons.settings),
  onSelected: (MenuType result) {
    setState(() {
      _selection = result;
    });
  },
  itemBuilder: (BuildContext context) =&amp;gt; MenuType.values
      .map((value) =&amp;gt; PopupMenuItem(
            value: value,
            child: Text(value.toShortString()),
          ))
      .toList(),
), &lt;/code&gt;&lt;/pre&gt;</description>
      <category>Flutter</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/25</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-%EB%B2%84%ED%8A%BC-2-ToggleButtons-DropdownButton-PopupMenuButton#entry25comment</comments>
      <pubDate>Sun, 18 Apr 2021 00:05:22 +0900</pubDate>
    </item>
    <item>
      <title>[플러터 2.0] 버튼 - (1) (TextButton, ElevatedButton,  OutlinedButton, IconButton, ButtonBar)</title>
      <link>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-%EB%B2%84%ED%8A%BC-1-TextButton-ElevatedButton-OutlinedButton-IconButton-ButtonBar</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;516&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4oMID/btq0TuzHb5v/uglamsKIVQ0Fwh2HNBhNt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4oMID/btq0TuzHb5v/uglamsKIVQ0Fwh2HNBhNt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4oMID/btq0TuzHb5v/uglamsKIVQ0Fwh2HNBhNt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4oMID%2Fbtq0TuzHb5v%2FuglamsKIVQ0Fwh2HNBhNt1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;516&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;플러터에서 버튼과 관련된 글을 보면 FlatButton, RaisedButton 등을 사용하는 것을 볼 수 있는데, Flutter (1.22)버젼부터는 FlatButton, RaisedButton, OutlineButton이 각각 &lt;code&gt;TextButton&lt;/code&gt;, &lt;code&gt;ElevatedButton&lt;/code&gt;, &lt;code&gt;OutlinedButton&lt;/code&gt;으로 업데이트 됐습니다.. (2.0이 아니라 그전 1.22부터 바뀐 겁니다)&lt;/p&gt;
&lt;p&gt;기본적인 사용 방법은 다음과 같습니다&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;TextButton or OutlinedButton or ElevatedButton(
    onPressed: () {},                  //@required
    onLongPress: () {},
    focusNode:,
    autofocus: true,
    clipBehavior: Clip.none,
    style: ButtonStyle(),// 가장 큰 변화! (나중에 더 자세히!)
    child: Widget(),                   //@required
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이중에 onPressed와 child parameter를 가장 많이 쓸 것 같네요&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;ElevatedButton(
            onPressed: () {},
            child: Text(&quot;ElevatedButton&quot;),
),&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저 dartpad를 이용해서 코드 예제와 실제 구현 결과가 어떤지 한번 보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;iframe style=&quot;width:900px;height:600px;&quot; src=&quot;https://dartpad.dev/embed-flutter.html?id=ce881b33bf40e09ab565f045833a25be&amp;amp;run=true&amp;amp;split=50&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;사용법 자체는 매우 간단한데, &lt;code&gt;TextButton&lt;/code&gt;, &lt;code&gt;ElevatedButton&lt;/code&gt;, &lt;code&gt;OutlinedButton&lt;/code&gt; 각 버튼마다 어떤 특징을 갖고 있을까요? 그리고 언제 사용하는 게 디자인 가이드라인에 맞는 걸까요?&lt;/p&gt;
&lt;h1&gt;ElevatedButton&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;214&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bS2G4Y/btq0UcZThYG/uGEDAPfnNdqBvGGUxZNMJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bS2G4Y/btq0UcZThYG/uGEDAPfnNdqBvGGUxZNMJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bS2G4Y/btq0UcZThYG/uGEDAPfnNdqBvGGUxZNMJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbS2G4Y%2Fbtq0UcZThYG%2FuGEDAPfnNdqBvGGUxZNMJ1%2Fimg.png&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;214&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ElevatedButton은 flat 한 layout (예를 들어 list)에 깊이감을 주기 위해서 사용합니다. 그래서 이미 깊이감이 있는 dialog 혹은 card에는 사용하는 것을 자제해야 합니다.&lt;/p&gt;
&lt;p&gt;ElevatedButton.icon을 이용하여 버튼에 아이콘을 넣을 수도 있습니다.&lt;/p&gt;
&lt;h1&gt;TextButton&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Untitled 1.png&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AkTFx/btq0VpSdG8L/28TCWfr0WzwZkSKdatSHkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AkTFx/btq0VpSdG8L/28TCWfr0WzwZkSKdatSHkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AkTFx/btq0VpSdG8L/28TCWfr0WzwZkSKdatSHkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAkTFx%2Fbtq0VpSdG8L%2F28TCWfr0WzwZkSKdatSHkk%2Fimg.png&quot; data-filename=&quot;Untitled 1.png&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;TextButton은 toolbar, diaglog 혹은 다른 content 사이에 사용을 하는데, 이때 패딩을 줘서 다른 content과 간격을 줘야 합니다. Text는 눈에 보이는 경계가 없기 때문에 상대적인 위치로 다른 content과 차별시켜야 합니다.&lt;/p&gt;
&lt;p&gt;ElevatedButton와 마찬가지로 TextButton.icon을 이용하여 버튼에 아이콘을 넣을 수도 있다.&lt;/p&gt;
&lt;h1&gt;OutlinedButton&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Untitled 2.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;176&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bovGBh/btq0Pc7TjpC/bdkDB5uLuBKCEPBjikD9Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bovGBh/btq0Pc7TjpC/bdkDB5uLuBKCEPBjikD9Y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bovGBh/btq0Pc7TjpC/bdkDB5uLuBKCEPBjikD9Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbovGBh%2Fbtq0Pc7TjpC%2FbdkDB5uLuBKCEPBjikD9Y0%2Fimg.png&quot; data-filename=&quot;Untitled 2.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;176&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;OutlinedButton은 ElevatedButton과 TextButton사이의 강도를 가지는 위젯입니다&lt;/p&gt;
&lt;p&gt;OutlinedButton의 action은 중요한데, 앱에서 가장 우선수위가 높은 action은 아닙니다.&lt;/p&gt;
&lt;p&gt;역시나, OutlinedButton.icon을 이용하여 버튼에 아이콘을 넣을수도 있다.&lt;/p&gt;
&lt;p&gt;위 버튼들에서 버튼. icon을 이용하면 왼쪽에 아이콘이 생기게 할 수 있는데, 만약 text(label)은 따로 필요 없고 아이콘만 필요한 경우에는 &lt;code&gt;IconButton&lt;/code&gt;을 이용하면 됩니다.&lt;/p&gt;
&lt;h1&gt;IconButton&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;242&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/O1pnb/btq0SFVNCvv/vMjkDvkbh0zzlrrEnA0eJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/O1pnb/btq0SFVNCvv/vMjkDvkbh0zzlrrEnA0eJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/O1pnb/btq0SFVNCvv/vMjkDvkbh0zzlrrEnA0eJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FO1pnb%2Fbtq0SFVNCvv%2FvMjkDvkbh0zzlrrEnA0eJk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;242&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위의 버튼들과는 다르게 child가 아니라 icon parameter를 갖고 있습니다&lt;/p&gt;
&lt;p&gt;그리고 또 다른 특이점으로는 iconSize를 통해서 버튼의 크기를 조정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/material/IconButton/icon.html&quot;&gt;icon&lt;/a&gt;&lt;/b&gt; &amp;rarr; &lt;a href=&quot;https://api.flutter.dev/flutter/widgets/Widget-class.html&quot;&gt;Widget&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/material/IconButton/iconSize.html&quot;&gt;iconSize&lt;/a&gt;&lt;/b&gt; &amp;rarr; &lt;a href=&quot;https://api.flutter.dev/flutter/dart-core/double-class.html&quot;&gt;double&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;ButtonBar&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;468&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n1yQi/btq0PdeEYKU/eNa6qBKSrWiglSOhULTLYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n1yQi/btq0PdeEYKU/eNa6qBKSrWiglSOhULTLYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n1yQi/btq0PdeEYKU/eNa6qBKSrWiglSOhULTLYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn1yQi%2Fbtq0PdeEYKU%2FeNa6qBKSrWiglSOhULTLYk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;468&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;ButtonBar(
  children: [
    TextButton(
      onPressed: () {},
      child: Text(&quot;TextButton&quot;),
    ),
    ElevatedButton(
      onPressed: () {},
      child: Text(&quot;ElevatedButton&quot;),
    ),
  ],
),&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ButtonBar는 end-aligned 정렬의 버튼 Row입니다.&lt;/p&gt;
&lt;p&gt;다만, 공간이 부족한 경우네는 column으로 layout 됩니다.&lt;/p&gt;
&lt;p&gt;가장 많이 쓰이는 경우는 card와 dialog에서 button들을 정렬해주는 역할을 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;TextButton, ElevatedButton, OutlinedButton, IconButton과 같이 버튼은 여러 가지가 존재하지만 각자마다 그 쓰임새가 존재합니다.&lt;/p&gt;
&lt;p&gt;구글의 Material 홈페이지에서 디자인 가이드라인을 볼 수도 있습니다&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.io/design/components/buttons.html&quot;&gt;https://material.io/design/components/buttons.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;+&lt;span&gt;&amp;alpha;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기까지는 단일(?) 버튼에 대한 소개였고, 만약 멀티(?) 버튼 (아래 움짤과 같은 버튼)에 대해서 알고 싶다면&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-%EB%B2%84%ED%8A%BC-2-ToggleButtons-DropdownButton-PopupMenuButton&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기서&lt;/a&gt; 보시면 됩니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OCr6a/btq4kVhM7lk/1JJGC2WzIKG69y3oAuQWrK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OCr6a/btq4kVhM7lk/1JJGC2WzIKG69y3oAuQWrK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OCr6a/btq4kVhM7lk/1JJGC2WzIKG69y3oAuQWrK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/OCr6a/btq4kVhM7lk/1JJGC2WzIKG69y3oAuQWrK/img.gif&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter/Widget</category>
      <category>button</category>
      <category>dartpad</category>
      <category>Flutter</category>
      <category>flutter2.0</category>
      <category>버튼</category>
      <category>프러터2</category>
      <category>플러터</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/24</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-%EB%B2%84%ED%8A%BC-1-TextButton-ElevatedButton-OutlinedButton-IconButton-ButtonBar#entry24comment</comments>
      <pubDate>Wed, 24 Mar 2021 00:44:50 +0900</pubDate>
    </item>
    <item>
      <title>[플러터 2.0] LayoutBuilder (반응형 레이아웃 만들기)</title>
      <link>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-LayoutBuilder-%EB%B0%98%EC%9D%91%ED%98%95-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이전 글에서는 MediaQuery를 이용해서 기기의 화면 크기를 알아보는 법을 배웠습니다&lt;/p&gt;
&lt;p&gt;하지만 기기의 전체 화면이 아니라 &lt;b&gt;위젯의 크기를&lt;/b&gt; 알고싶을때는 어떻게 해야 할까요?&lt;/p&gt;
&lt;p&gt;물론 MediaQuery를 쓰고, 각 위젯의 height, widght를 구해서 빼줘서 어쩠지해서 구할 수는 있지만&lt;/p&gt;
&lt;p&gt;이 모든 것을 한방에 쉽게 해결하는 것이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;LayoutBuilder&lt;/b&gt;&lt;/span&gt; 위젯입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;구글 공신 문서에서는 &lt;code&gt;Builds a widget tree that can depend on the parent widget's size.&lt;/code&gt; 라고 소개하고 있습니다. 말 그대로 위젯의 크기에 따라 build를 하겠다는 뜻입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;LayoutBuilder의 builder function은 layout타임에 불리게 되고, constraints이 제공됩니다.&lt;/p&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;builder: (BuildContext context, BoxConstraints constraints) {
        final width = constraints.maxWidth;
        final height = constraints.maxHeight;
        final ratio = width / height;
        .
        .
        .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;builder function은&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;처음으로 widget이 layout 될 때&lt;/li&gt;
&lt;li&gt;부모 widget의 constraint가 바뀔 때&lt;/li&gt;
&lt;li&gt;부모 widget이 해당 widget을 업데이트할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;불리게 됩니다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이해를 돕고자 예시를 가져와봤습니다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;iframe style=&quot;width:900px;height:600px;&quot; src=&quot;https://dartpad.dev/embed-flutter.html?id=b3872cd1e9447baec25a7acb4722f350&amp;run=true&amp;split=50&quot;&gt;&lt;/iframe&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;부모 widget이 같은 값의 constraint를 계속 넘겨주게 되는 상황에서는 builder function이 불리지 않습니다&lt;/p&gt;
&lt;p&gt;LayoutBuilder는 MediaQuery와 함께 아래의 예시처럼 reponsive 하게 화면을 구성하고 싶을 때 사용됩니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mWGFd/btq0HanK053/axtlnxiRteDnt4W7UcKfg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mWGFd/btq0HanK053/axtlnxiRteDnt4W7UcKfg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mWGFd/btq0HanK053/axtlnxiRteDnt4W7UcKfg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmWGFd%2Fbtq0HanK053%2FaxtlnxiRteDnt4W7UcKfg1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;MediaQuery 위젯에 대해서 알고 싶으면 &lt;a href=&quot;https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B020-MediaQuery-%EA%B8%B0%EA%B8%B0-%EC%A0%95%EB%B3%B4-%EA%B5%AC%ED%95%98%EA%B8%B0&quot;&gt;여기로&lt;/a&gt; 가주세요&lt;/p&gt;
&lt;h3&gt;참고 자료&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html&quot;&gt;https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>Flutter/Widget</category>
      <category>Flutter</category>
      <category>layoutbuilder</category>
      <category>반응형</category>
      <category>플러터</category>
      <category>플러터2.0</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/23</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-20-LayoutBuilder-%EB%B0%98%EC%9D%91%ED%98%95-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EB%A7%8C%EB%93%A4%EA%B8%B0#entry23comment</comments>
      <pubDate>Sun, 21 Mar 2021 22:56:53 +0900</pubDate>
    </item>
    <item>
      <title>[플러터2.0] MediaQuery (기기 정보 구하기)</title>
      <link>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B020-MediaQuery-%EA%B8%B0%EA%B8%B0-%EC%A0%95%EB%B3%B4-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;썸네일.png&quot; data-origin-width=&quot;275&quot; data-origin-height=&quot;183&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHBg2H/btq0DrwNKiR/NWbUc28BY7JSaEsxaMoge1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHBg2H/btq0DrwNKiR/NWbUc28BY7JSaEsxaMoge1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHBg2H/btq0DrwNKiR/NWbUc28BY7JSaEsxaMoge1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHBg2H%2Fbtq0DrwNKiR%2FNWbUc28BY7JSaEsxaMoge1%2Fimg.png&quot; data-filename=&quot;썸네일.png&quot; data-origin-width=&quot;275&quot; data-origin-height=&quot;183&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;22749d9d-e3e6-4372-b77c-b147e5ded51b&quot;&gt;MediaQuery 위젯을 쓰는 가장 대표적인 이유는 현재 기기의 &lt;b&gt;화면 크기&lt;/b&gt;를 구할때 찾기 위해입니다&lt;/p&gt;
&lt;p id=&quot;d4df4e53-ba6a-46be-8297-2559024933ef&quot;&gt;화면 크기는 MediaQuery.of(context).size 을 통해서 알 수 있습니다.&lt;/p&gt;
&lt;p id=&quot;0f9d0f33-7549-401e-b316-e61d57fde44a&quot;&gt;그리고 MediaQuery.of 을 이용할때는 media query가 변할때마다 widget이 rebuild됩니다&lt;/p&gt;
&lt;p id=&quot;329ca33e-e5a4-4a6b-b190-90e8af81fc4d&quot;&gt;&lt;i&gt;보통 기기가 회전될때 가장 많이 변합니다 (혹은 웹에서는 창 크기를 조절할때)&lt;/i&gt;&lt;/p&gt;
&lt;p id=&quot;005261a2-991a-4fab-99fc-1e1ef2b6d925&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;b6d305e2-6d76-4025-a2e1-39355d572e28&quot;&gt;사실 mediaquery.of 을 하게되면 반환되는 값을 MediaQueryData인데&lt;/p&gt;
&lt;p&gt;size 말고도 기기와 관련된 정보를 많이 담고 있습니다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;설명을 도와드리기 위해서 예제 코드를 가져왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;iframe style=&quot;width:900px;height:600px;&quot; src=&quot;https://dartpad.dev/embed-flutter.html?id=a5e9fe7672bf1758190e41dc255a9b25&amp;run=true&amp;split=50&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;86beded6-5939-45a0-b83a-b29b43ab4f41&quot;&gt;MediaQueryData&lt;/h2&gt;
&lt;p id=&quot;2035c4e8-3413-4880-9cbb-ead170fac2dd&quot;&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/widgets/MediaQueryData/orientation.html&quot;&gt;&lt;b&gt;orientation&lt;/b&gt;&lt;/a&gt;&amp;nbsp;&amp;rarr;&amp;nbsp;&lt;a href=&quot;https://api.flutter.dev/flutter/widgets/Orientation-class.html&quot;&gt;Orientation&lt;/a&gt;&lt;/p&gt;
&lt;p id=&quot;899b6f57-c03e-4dfe-ae05-f23b4db4d2fd&quot;&gt;기기의 방향 (landscape 혹은 portrait)&lt;/p&gt;
&lt;p id=&quot;cc566bff-c07c-4093-94ba-8b57f6bb0c14&quot;&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/widgets/MediaQueryData/padding.html&quot;&gt;&lt;b&gt;padding&lt;/b&gt;&lt;/a&gt;&amp;nbsp;&amp;rarr;&amp;nbsp;&lt;a href=&quot;https://api.flutter.dev/flutter/painting/EdgeInsets-class.html&quot;&gt;EdgeInsets&lt;/a&gt;&lt;/p&gt;
&lt;p id=&quot;1cda97e9-6780-43d5-ba51-f39ea7000df1&quot;&gt;System UI 로 인해 완전히 가려진 부분 (일반적으로 노치 혹은 status bar)&lt;/p&gt;
&lt;p id=&quot;c3b809a2-7bfd-4b94-9353-a89294e9f18e&quot;&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/widgets/MediaQueryData/viewInsets.html&quot;&gt;&lt;b&gt;viewInsets&lt;/b&gt;&lt;/a&gt;&amp;nbsp;&amp;rarr;&amp;nbsp;&lt;a href=&quot;https://api.flutter.dev/flutter/painting/EdgeInsets-class.html&quot;&gt;EdgeInsets&lt;/a&gt;&lt;/p&gt;
&lt;p id=&quot;a1e681de-e4b0-4c00-bbc5-01ebd84d5d98&quot;&gt;System UI 로 인해 완전히 가려진 부분 (일반적으로 키보드)&lt;/p&gt;
&lt;p id=&quot;187564cb-a8f6-4dcf-92b0-821bd95e0fb9&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;240bbf5a-393d-43b0-afbc-8bcd33b0314c&quot;&gt;참고 자료&lt;/h3&gt;
&lt;p id=&quot;6bbaf467-0421-4f04-b9e3-88321372623a&quot;&gt;&lt;a href=&quot;https://api.flutter.dev/flutter/widgets/MediaQuery-class.html&quot;&gt;https://api.flutter.dev/flutter/widgets/MediaQuery-class.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>Flutter/Widget</category>
      <author>mike123789-dev</author>
      <guid isPermaLink="true">https://mike123789-dev.tistory.com/22</guid>
      <comments>https://mike123789-dev.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B020-MediaQuery-%EA%B8%B0%EA%B8%B0-%EC%A0%95%EB%B3%B4-%EA%B5%AC%ED%95%98%EA%B8%B0#entry22comment</comments>
      <pubDate>Sun, 21 Mar 2021 22:27:13 +0900</pubDate>
    </item>
  </channel>
</rss>