iOS Custom Button with Label

GitHub contribution graph

Implementing a custom button featuring a label, using Swift5 and UIKit 🕹

Creating our button class

We start by creating a new file, ButtonWithLabel. To keep our button customizable, we initialize our class with a type and an action.

<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIKit</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">class</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">ButtonWithLabel</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIView </span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">typealias</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Action</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> (() </span><span style="color: var(--shiki-token-keyword)">-&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Void</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">?</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> action: (() </span><span style="color: var(--shiki-token-keyword)">-&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Void</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">?</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">enum</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">ButtonWithLabelType</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> info</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> alert</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> type: ButtonWithLabelType</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">init</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">type</span><span style="color: var(--shiki-color-text)">: ButtonWithLabelType) {</span></span>
<span><span style="color: var(--shiki-color-text)">        self.type </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> type</span></span>
<span><span style="color: var(--shiki-color-text)">        super.</span><span style="color: var(--shiki-token-keyword)">init</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">frame</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .null</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">   }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">required</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">init?</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">coder</span><span style="color: var(--shiki-color-text)">: NSCoder) {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-function)">fatalError</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;init(coder:) has not been implemented&quot;</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">@discardableResult</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">func</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">with</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">action</span><span style="color: var(--shiki-color-text)">: Action) </span><span style="color: var(--shiki-token-keyword)">-&gt;</span><span style="color: var(--shiki-color-text)"> Self {</span></span>
<span><span style="color: var(--shiki-color-text)">        self.action </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> action</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> self</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">@objc</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">func</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">click</span><span style="color: var(--shiki-color-text)">() {</span></span>
<span><span style="color: var(--shiki-color-text)">        action</span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)">()</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span></span>

Creating the label and the icon

Because we want the entire class to be pressable, we create both our label and our button as UIButton elements, and we add the previously created click function as the buttons click-targets. I've also added some simple styling to the label button, giving it some padding and a background color. We will style the button in the next step.

<span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">lazy</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> label: UIButton </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> button </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIButton</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span><span style="color: var(--shiki-color-text)">    button.contentEdgeInsets </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIEdgeInsets</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">top</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-function)">, left</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-function)">, bottom</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-function)">, right</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    button.backgroundColor </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> .white.</span><span style="color: var(--shiki-token-function)">withAlphaComponent</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-constant)">0.8</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    button.</span><span style="color: var(--shiki-token-function)">addTarget</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">self, action</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> #selector</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">click</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .touchUpInside</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> button</span></span>
<span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">lazy</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> icon: UIButton </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> button </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIButton</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span><span style="color: var(--shiki-color-text)">    button.</span><span style="color: var(--shiki-token-function)">addTarget</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">self, action</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> #selector</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">click</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .touchUpInside</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> button</span></span>
<span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span></span>

Setting the label text and styling the icon

We want to create our label text and choose our icon based on the provided ButtonWithLabelType. To do this, we create a helper function, updateStyling(). In this example, I've used icons from SF Symbols.

<span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">func</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">updateStyling</span><span style="color: var(--shiki-color-text)">() {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">switch</span><span style="color: var(--shiki-color-text)"> type {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> .info</span><span style="color: var(--shiki-token-keyword)">:</span></span>
<span><span style="color: var(--shiki-color-text)">        label.</span><span style="color: var(--shiki-token-function)">setTitle</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Info&quot;</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        icon.</span><span style="color: var(--shiki-token-function)">setImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">UIImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">systemName</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;questionmark.circle&quot;</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> .alert</span><span style="color: var(--shiki-token-keyword)">:</span></span>
<span><span style="color: var(--shiki-color-text)">        label.</span><span style="color: var(--shiki-token-function)">setTitle</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Alert&quot;</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        icon.</span><span style="color: var(--shiki-token-function)">setImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">UIImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">systemName</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;exclamationmark.circle&quot;</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Positioning

We update our init function to call the newly created updateStyling. We also place our label and our icon in a UIStackView.

<span><span style="color: var(--shiki-token-keyword)">init</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">type</span><span style="color: var(--shiki-color-text)">: ButtonWithLabelType) {</span></span>
<span><span style="color: var(--shiki-color-text)">    self.type </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> type</span></span>
<span><span style="color: var(--shiki-color-text)">    super.</span><span style="color: var(--shiki-token-keyword)">init</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">frame</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .null</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">updateStyling</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> stack </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIStackView</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">arrangedSubviews</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> [label, icon]</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    stack.</span><span style="color: var(--shiki-token-constant)">alignment</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> .center</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">addSubview</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">stack</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    stack.</span><span style="color: var(--shiki-token-function)">fillInSuperview</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Usage

We can now start using our new button by setting a type and giving it an action. In this example, I use it as a rightBarButtonItem.

<span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> infoButton </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">ButtonWithLabel</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">type</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .info</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-function)">with</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">action</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> showInfoView</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">navigationItem.rightBarButtonItem </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIBarButtonItem</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">customView</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> infoButton</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span></span>

And that's it! Here is the completed class:

<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIKit</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">class</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">ButtonWithLabel</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIView </span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">typealias</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Action</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> (() </span><span style="color: var(--shiki-token-keyword)">-&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Void</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">?</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> action: (() </span><span style="color: var(--shiki-token-keyword)">-&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Void</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">?</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">enum</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">ButtonWithLabelType</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> info</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> alert</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> type: ButtonWithLabelType</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">lazy</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> label: UIButton </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> button </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIButton</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span><span style="color: var(--shiki-color-text)">        button.contentEdgeInsets </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIEdgeInsets</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">top</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-function)">, left</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-function)">, bottom</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-function)">, right</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-constant)">6</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        button.backgroundColor </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> .white.</span><span style="color: var(--shiki-token-function)">withAlphaComponent</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-constant)">0.8</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        button.</span><span style="color: var(--shiki-token-function)">addTarget</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">self, action</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> #selector</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">click</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .touchUpInside</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> button</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">lazy</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">var</span><span style="color: var(--shiki-color-text)"> icon: UIButton </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> button </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIButton</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span><span style="color: var(--shiki-color-text)">        button.</span><span style="color: var(--shiki-token-function)">addTarget</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">self, action</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> #selector</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">click</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .touchUpInside</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> button</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">init</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">type</span><span style="color: var(--shiki-color-text)">: ButtonWithLabelType) {</span></span>
<span><span style="color: var(--shiki-color-text)">        self.type </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> type</span></span>
<span><span style="color: var(--shiki-color-text)">        super.</span><span style="color: var(--shiki-token-keyword)">init</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">frame</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .null</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-function)">updateStyling</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> stack </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">UIStackView</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">arrangedSubviews</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> [label, icon]</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        stack.</span><span style="color: var(--shiki-token-constant)">alignment</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> .center</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-function)">addSubview</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">stack</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        stack.</span><span style="color: var(--shiki-token-function)">fillInSuperview</span><span style="color: var(--shiki-token-punctuation)">()</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">required</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">init?</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">coder</span><span style="color: var(--shiki-color-text)">: NSCoder) {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-function)">fatalError</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;init(coder:) has not been implemented&quot;</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">func</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">updateStyling</span><span style="color: var(--shiki-color-text)">() {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">switch</span><span style="color: var(--shiki-color-text)"> type {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> .info</span><span style="color: var(--shiki-token-keyword)">:</span></span>
<span><span style="color: var(--shiki-color-text)">            label.</span><span style="color: var(--shiki-token-function)">setTitle</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Info&quot;</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">            icon.</span><span style="color: var(--shiki-token-function)">setImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">UIImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">systemName</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;questionmark.circle&quot;</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">case</span><span style="color: var(--shiki-color-text)"> .alert</span><span style="color: var(--shiki-token-keyword)">:</span></span>
<span><span style="color: var(--shiki-color-text)">            label.</span><span style="color: var(--shiki-token-function)">setTitle</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Alert&quot;</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">            icon.</span><span style="color: var(--shiki-token-function)">setImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">UIImage</span><span style="color: var(--shiki-token-punctuation)">(</span><span style="color: var(--shiki-token-function)">systemName</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;exclamationmark.circle&quot;</span><span style="color: var(--shiki-token-punctuation)">)</span><span style="color: var(--shiki-token-function)">, for</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-token-function)"> .normal</span><span style="color: var(--shiki-token-punctuation)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        }</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">@discardableResult</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">func</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">with</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">action</span><span style="color: var(--shiki-color-text)">: Action) </span><span style="color: var(--shiki-token-keyword)">-&gt;</span><span style="color: var(--shiki-color-text)"> Self {</span></span>
<span><span style="color: var(--shiki-color-text)">        self.action </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> action</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> self</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">@objc</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">private</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">func</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">click</span><span style="color: var(--shiki-color-text)">() {</span></span>
<span><span style="color: var(--shiki-color-text)">        action</span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)">()</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>