<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="https://publishpress.com/"
	>

<channel>
	<title>swiftui Archives - Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/tag/swiftui/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/tag/swiftui/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Thu, 21 Dec 2023 02:02:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.tomosia.com.vn/wp-content/uploads/2023/09/cropped-icon-32x32.png</url>
	<title>swiftui Archives - Tomoshare</title>
	<link>https://blog.tomosia.com.vn/tag/swiftui/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Custom View Modifiers trong SwiftUI</title>
		<link>https://blog.tomosia.com.vn/custom-view-modifiers-trong-swiftui/</link>
					<comments>https://blog.tomosia.com.vn/custom-view-modifiers-trong-swiftui/#comments</comments>
		
		<dc:creator><![CDATA[Thanh Nguyen]]></dc:creator>
		<pubDate>Thu, 21 Dec 2023 02:02:30 +0000</pubDate>
				<category><![CDATA[IOS]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[swiftui]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=2616</guid>

					<description><![CDATA[<p>What are “View Modifiers”? Trong SwiftUI, view modifiers là một cách để thay đổi hoặc thiết lập hành&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/custom-view-modifiers-trong-swiftui/">Custom View Modifiers trong SwiftUI</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h5 class="wp-block-heading has-cyan-bluish-gray-color has-text-color has-link-color wp-elements-141539c128789e447cbcf37c3824adf3" id="4988"><span id="what-are-view-modifiers">What are “View Modifiers”?</span></h5>



<pre class="wp-block-preformatted">Trong SwiftUI, view modifiers là một cách để thay đổi hoặc thiết lập hành vi cho một view cụ thể. Chúng là các cấu trúc nhẹ nhàng cho phép bạn thay đổi giao diện, hành vi hoặc bố cục của một view. Các bộ điều chỉnh view được áp dụng bằng cách sử dụng cú pháp dấu chấm và có thể được nối với nhau để thực hiện những sửa đổi phức tạp hơn.

View modifiers không chỉ cho phép bạn thay đổi hình dạng và hành vi của một view, mà còn cho phép bạn tạo ra những thay đổi phức tạp bằng cách nối chúng lại với nhau. Với SwiftUI, bạn có thể thay đổi font, màu sắc, khoảng trống, căn chỉnh, và nhiều tính năng khác của view chỉ bằng cú pháp đơn giản.

Ngoài ra, SwiftUI cung cấp các view modifier tích hợp sẵn, giúp bạn tiết kiệm thời gian và công sức trong việc tạo ra giao diện người dùng đẹp và hiệu quả. Hơn nữa, bạn cũng có thể tạo ra những bộ điều chỉnh tùy chỉnh phù hợp với yêu cầu cụ thể của ứng dụng của mình.
</pre>



<p>Trong SwiftUI, view modifiers là một cách hữu dụng để có thể đóng gói và tái sử dụng các hành vi và styles cho các view. </p>



<p>Bạn có thể làm điều này bằng cách tạo một struct <strong>ViewModifier</strong> mới với giao thức <strong>ViewModifier</strong>. Ở đây, mình tạo một struct <strong>CustomViewModifier</strong> và tuân thủ nó vào giao thức <strong>ViewModifier</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code="struct CustomViewModifier: ViewModifier {

    func body(content: Content) -&gt; some View {
        content
    }

}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">struct</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CustomViewModifier</span><span style="color: #F6F6F4">: ViewModifier {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">body</span><span style="color: #F6F6F4">(</span><span style="color: #62E884; font-style: italic">content</span><span style="color: #F6F6F4">: Content) </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        content</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>Bây giờ, bạn có thể thêm các modifier vào content này theo ý muốn. Mình sẽ thêm một số view modifier tích hợp sẵn để thêm border.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code="struct CustomViewModifier: ViewModifier {

    func body(content: Content) -&gt; some View {
        content
            .padding()
            .cornerRadius(10)
            .overlay(
                RoundedRectangle(cornerRadius: 10)
                    .stroke(Color.black, lineWidth: 2)
            )
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">struct</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CustomViewModifier</span><span style="color: #F6F6F4">: ViewModifier {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">body</span><span style="color: #F6F6F4">(</span><span style="color: #62E884; font-style: italic">content</span><span style="color: #F6F6F4">: Content) </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        content</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">padding</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">overlay</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #97E1F1">RoundedRectangle</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">                    .</span><span style="color: #97E1F1">stroke</span><span style="color: #F6F6F4">(Color.black, </span><span style="color: #97E1F1">lineWidth</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">            )</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>Chúng ta có thể tùy chỉnh các thuộc tính của bộ điều chỉnh view như corner radius, border width, v.v. </p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code="struct CustomViewModifier: ViewModifier {
    
    var cornerRadius: CGFloat
    var borderColor: Color
    var borderWidth: CGFloat

    func body(content: Content) -&gt; some View {
        content
            .padding()
            .cornerRadius(cornerRadius)
            .overlay(
                RoundedRectangle(cornerRadius: cornerRadius)
                    .stroke(borderColor, lineWidth: borderWidth)
            )
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">struct</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">CustomViewModifier</span><span style="color: #F6F6F4">: ViewModifier {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> cornerRadius: CGFloat</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> borderColor: Color</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> borderWidth: CGFloat</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">body</span><span style="color: #F6F6F4">(</span><span style="color: #62E884; font-style: italic">content</span><span style="color: #F6F6F4">: Content) </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        content</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">padding</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">(cornerRadius)</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">overlay</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #97E1F1">RoundedRectangle</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: cornerRadius)</span></span>
<span class="line"><span style="color: #F6F6F4">                    .</span><span style="color: #97E1F1">stroke</span><span style="color: #F6F6F4">(borderColor, </span><span style="color: #97E1F1">lineWidth</span><span style="color: #F6F6F4">: borderWidth)</span></span>
<span class="line"><span style="color: #F6F6F4">            )</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>Chúng ta có thể gọi trực tiếp custom modifier này hoặc bạn có thể đặt một tên cho nó bằng cách tạo extension từ <strong>View</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4296875px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code=".modifier(CustomViewModifier(cornerRadius: 10, 
                             borderColor: .black, 
                             borderWidth: 2)) " style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">.</span><span style="color: #97E1F1">modifier</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">CustomViewModifier</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">10</span><span style="color: #F6F6F4">, </span></span>
<span class="line"><span style="color: #F6F6F4">                             </span><span style="color: #97E1F1">borderColor</span><span style="color: #F6F6F4">: .black, </span></span>
<span class="line"><span style="color: #F6F6F4">                             </span><span style="color: #97E1F1">borderWidth</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">)) </span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code="extension View{
    //--Chúng ta có thể đặt tên cho custom modifer
    func addBorder(cornerRadius: CGFloat, 
                   borderColor: Color,
                   borderWidth: CGFloat) -&gt; some View{
        self.modifier(CustomViewModifier(cornerRadius: cornerRadius, 
                                         borderColor: borderColor,
                                         borderWidth: borderWidth))
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">extension</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">View</span><span style="color: #F6F6F4">{</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">//--Chúng ta có thể đặt tên cho custom modifer</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">addBorder</span><span style="color: #F6F6F4">(</span><span style="color: #62E884; font-style: italic">cornerRadius</span><span style="color: #F6F6F4">: CGFloat, </span></span>
<span class="line"><span style="color: #F6F6F4">                   </span><span style="color: #62E884; font-style: italic">borderColor</span><span style="color: #F6F6F4">: Color,</span></span>
<span class="line"><span style="color: #F6F6F4">                   </span><span style="color: #62E884; font-style: italic">borderWidth</span><span style="color: #F6F6F4">: CGFloat) </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View{</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #BF9EEE; font-style: italic">self</span><span style="color: #F6F6F4">.</span><span style="color: #97E1F1">modifier</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">CustomViewModifier</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: cornerRadius, </span></span>
<span class="line"><span style="color: #F6F6F4">                                         </span><span style="color: #97E1F1">borderColor</span><span style="color: #F6F6F4">: borderColor,</span></span>
<span class="line"><span style="color: #F6F6F4">                                         </span><span style="color: #97E1F1">borderWidth</span><span style="color: #F6F6F4">: borderWidth))</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>Bây giờ hãy sử dụng modifier này trong view của bạn.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code="struct ContentView: View {
    var body: some View {
        VStack {
            Text(&quot;Hello, world!&quot;)
                .addBorder(cornerRadius: 8, 
                           borderColor: Color.blue, 
                           borderWidth: 2)
        }
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">struct</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">ContentView</span><span style="color: #F6F6F4">: View {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> body: </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        VStack {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #97E1F1">Text</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Hello, world!</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">                .</span><span style="color: #97E1F1">addBorder</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">8</span><span style="color: #F6F6F4">, </span></span>
<span class="line"><span style="color: #F6F6F4">                           </span><span style="color: #97E1F1">borderColor</span><span style="color: #F6F6F4">: Color.blue, </span></span>
<span class="line"><span style="color: #F6F6F4">                           </span><span style="color: #97E1F1">borderWidth</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>Kết quả chúng ta sẽ được như hình bên dưới: </p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="369" height="231" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/1_9-VoC_PsPrFMjSVm3r3aPg-edited.webp" alt="" class="wp-image-2687" style="width:405px;height:auto" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/1_9-VoC_PsPrFMjSVm3r3aPg-edited.webp 369w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/1_9-VoC_PsPrFMjSVm3r3aPg-edited-300x188.webp 300w" sizes="(max-width: 369px) 100vw, 369px" /></figure>
</div>


<p>Thêm một ví dụ custom modifier với Linear Gradient: Tạo một view modifier có background là linear gradient và có thể blur.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Swift</span><span role="button" tabindex="0" data-code="struct BlurWithLinearGradient: ViewModifier {
    let isBlur: Bool
    let cornerRadius: CGFloat
    
    func body(content: Content) -&gt; some View {
        ZStack {
            if isBlur {
                content
                    .background(linearGradient())
                    .blur(radius: 3)
            }

            content
                .background(linearGradient())
        }
    }
    
    @ViewBuilder
    private func linearGradient() -&gt; some View {
        LinearGradient(colors: [Colors.black, Colors.blue],
                       startPoint: .topLeading,
                       endPoint: .bottomTrailing)
            .overlay(
                RoundedRectangle(cornerRadius: cornerRadius)
                    .strokeBorder(.white.opacity(0.5), lineWidth: 1)
            )
            .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
    }
}

extension View {
    func linearGradientBlur(isBlur: Bool = false, 
                            cornerRadius: CGFloat = 15) -&gt; some View {
        self.modifier(BlurWithLinearGradient(isBlur: isBlur, 
                                             cornerRadius: cornerRadius))
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">struct</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">BlurWithLinearGradient</span><span style="color: #F6F6F4">: ViewModifier {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">let</span><span style="color: #F6F6F4"> isBlur: </span><span style="color: #97E1F1; font-style: italic">Bool</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">let</span><span style="color: #F6F6F4"> cornerRadius: CGFloat</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">body</span><span style="color: #F6F6F4">(</span><span style="color: #62E884; font-style: italic">content</span><span style="color: #F6F6F4">: Content) </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        ZStack {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> isBlur {</span></span>
<span class="line"><span style="color: #F6F6F4">                content</span></span>
<span class="line"><span style="color: #F6F6F4">                    .</span><span style="color: #97E1F1">background</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">linearGradient</span><span style="color: #F6F6F4">())</span></span>
<span class="line"><span style="color: #F6F6F4">                    .</span><span style="color: #97E1F1">blur</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">radius</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">3</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">            }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">            content</span></span>
<span class="line"><span style="color: #F6F6F4">                .</span><span style="color: #97E1F1">background</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">linearGradient</span><span style="color: #F6F6F4">())</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">@ViewBuilder</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">linearGradient</span><span style="color: #F6F6F4">() </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1">LinearGradient</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">colors</span><span style="color: #F6F6F4">: [Colors.black, Colors.blue],</span></span>
<span class="line"><span style="color: #F6F6F4">                       </span><span style="color: #97E1F1">startPoint</span><span style="color: #F6F6F4">: .topLeading,</span></span>
<span class="line"><span style="color: #F6F6F4">                       </span><span style="color: #97E1F1">endPoint</span><span style="color: #F6F6F4">: .bottomTrailing)</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">overlay</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #97E1F1">RoundedRectangle</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: cornerRadius)</span></span>
<span class="line"><span style="color: #F6F6F4">                    .</span><span style="color: #97E1F1">strokeBorder</span><span style="color: #F6F6F4">(.white.</span><span style="color: #97E1F1">opacity</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">0.5</span><span style="color: #F6F6F4">), </span><span style="color: #97E1F1">lineWidth</span><span style="color: #F6F6F4">: </span><span style="color: #BF9EEE">1</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">            )</span></span>
<span class="line"><span style="color: #F6F6F4">            .</span><span style="color: #97E1F1">clipShape</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">RoundedRectangle</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: cornerRadius))</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">extension</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">View</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">func</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">linearGradientBlur</span><span style="color: #F6F6F4">(</span><span style="color: #62E884; font-style: italic">isBlur</span><span style="color: #F6F6F4">: </span><span style="color: #97E1F1; font-style: italic">Bool</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4">, </span></span>
<span class="line"><span style="color: #F6F6F4">                            </span><span style="color: #62E884; font-style: italic">cornerRadius</span><span style="color: #F6F6F4">: CGFloat </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">15</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">some</span><span style="color: #F6F6F4"> View {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #BF9EEE; font-style: italic">self</span><span style="color: #F6F6F4">.</span><span style="color: #97E1F1">modifier</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">BlurWithLinearGradient</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1">isBlur</span><span style="color: #F6F6F4">: isBlur, </span></span>
<span class="line"><span style="color: #F6F6F4">                                             </span><span style="color: #97E1F1">cornerRadius</span><span style="color: #F6F6F4">: cornerRadius))</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="380" height="233" src="http://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-18-at-09.57.57.png" alt="" class="wp-image-2689" style="width:358px;height:auto" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-18-at-09.57.57.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2023/12/Screenshot-2023-12-18-at-09.57.57-300x184.png 300w" sizes="(max-width: 380px) 100vw, 380px" /></figure>
</div>


<p><strong>References</strong>: <br><a href="https://developer.apple.com/documentation/swiftui/viewmodifier" target="_blank" rel="noreferrer noopener">https://developer.apple.com/documentation/swiftui/viewmodifier</a></p>
<p>The post <a href="https://blog.tomosia.com.vn/custom-view-modifiers-trong-swiftui/">Custom View Modifiers trong SwiftUI</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/custom-view-modifiers-trong-swiftui/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
