As we get started with Swift
and iOS
, we will see the familiar word Delegate
, which can be clearly seen in Apple’s frameworks. UITableView
and UICollectionView
are the most concrete examples of delegation in Swift. In this article, we will learn what delegate pattern
is and how to implement it in Swift.
Delegation pattern is a messaging design pattern in Swift, used in one-to-one communication between objects, taking advantage of the Swift protocol
to delegate to an object.
Let’s look at a simple example by creating a simple view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">class</span> <span class="token class-name">BubbleView</span> <span class="token punctuation">:</span> <span class="token builtin">UIView</span> <span class="token punctuation">{</span> <span class="token keyword">override</span> <span class="token keyword">init</span> <span class="token punctuation">(</span> frame <span class="token punctuation">:</span> <span class="token builtin">CGRect</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token keyword">init</span> <span class="token punctuation">(</span> frame <span class="token punctuation">:</span> frame <span class="token punctuation">)</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">required</span> <span class="token keyword">init</span> <span class="token operator">?</span> <span class="token punctuation">(</span> coder aDecoder <span class="token punctuation">:</span> <span class="token builtin">NSCoder</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token keyword">init</span> <span class="token punctuation">(</span> coder <span class="token punctuation">:</span> aDecoder <span class="token punctuation">)</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token keyword">func</span> <span class="token function">setup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> isUserInteractionEnabled <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">let</span> tapGestureRecognizer <span class="token operator">=</span> <span class="token function">UITapGestureRecognizer</span> <span class="token punctuation">(</span> target <span class="token punctuation">:</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> action <span class="token punctuation">:</span> # <span class="token function">selector</span> <span class="token punctuation">(</span> <span class="token builtin">BubbleView</span> <span class="token punctuation">.</span> didTapIntoButton <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> <span class="token function">addGestureRecognizer</span> <span class="token punctuation">(</span> tapGestureRecognizer <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token atrule">@objc</span> <span class="token keyword">func</span> <span class="token function">didTapIntoButton</span> <span class="token punctuation">(</span> <span class="token number">_</span> sender <span class="token punctuation">:</span> <span class="token builtin">UITapGestureRecognizer</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
We have a class called BubbleView
. Now define a delegate by writing a protocol
1 2 3 4 | <span class="token keyword">protocol</span> <span class="token builtin">BubbleViewDelegate</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">userDidTap</span> <span class="token punctuation">(</span> into bubbleView <span class="token punctuation">:</span> <span class="token builtin">BubbleView</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Please note that both Apple naming is Delegate at the end and methods in the “didDo” format.
Back to the class view, we now add a new property
1 2 3 4 5 6 7 8 9 | <span class="token keyword">class</span> <span class="token class-name">BubbleView</span> <span class="token punctuation">:</span> <span class="token builtin">UIView</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token keyword">weak</span> <span class="token keyword">var</span> delegate <span class="token punctuation">:</span> <span class="token builtin">BubbleViewDelegate</span> <span class="token operator">?</span> <span class="token atrule">@objc</span> <span class="token keyword">func</span> <span class="token function">didTapIntoButton</span> <span class="token punctuation">(</span> <span class="token number">_</span> sender <span class="token punctuation">:</span> <span class="token builtin">UITapGestureRecognizer</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> delegate <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">userDidTap</span> <span class="token punctuation">(</span> into <span class="token punctuation">:</span> <span class="token keyword">self</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Notice here we use weak
for the new property
. This avoids the possibility of having a retain cycle
as can be seen below
Here we want the view controller
have a bubble view
that can handle all UI interactions, such as touching a bubble view
. It can be seen that this is an MVC with a separate view and separate controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token keyword">class</span> <span class="token class-name">ContainerViewController</span> <span class="token punctuation">:</span> <span class="token builtin">UIViewController</span> <span class="token punctuation">{</span> <span class="token keyword">lazy</span> <span class="token keyword">var</span> bubbleView <span class="token punctuation">:</span> <span class="token builtin">BubbleView</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> bubbleView <span class="token operator">=</span> <span class="token function">BubbleView</span> <span class="token punctuation">(</span> frame <span class="token punctuation">:</span> <span class="token function">CGRect</span> <span class="token punctuation">(</span> x <span class="token punctuation">:</span> <span class="token number">90</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">,</span> width <span class="token punctuation">:</span> <span class="token number">200</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">200</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> bubbleView <span class="token punctuation">.</span> backgroundColor <span class="token operator">=</span> <span class="token punctuation">.</span> black bubbleView <span class="token punctuation">.</span> layer <span class="token punctuation">.</span> cornerRadius <span class="token operator">=</span> <span class="token number">100</span> bubbleView <span class="token punctuation">.</span> delegate <span class="token operator">=</span> <span class="token keyword">self</span> <span class="token keyword">return</span> bubbleView <span class="token punctuation">}</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">override</span> <span class="token keyword">func</span> <span class="token function">loadView</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">loadView</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> view <span class="token punctuation">.</span> <span class="token function">addSubview</span> <span class="token punctuation">(</span> bubbleView <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">extension</span> <span class="token builtin">ContainerViewController</span> <span class="token punctuation">:</span> <span class="token builtin">BubbleViewDelegate</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">userDidTap</span> <span class="token punctuation">(</span> into bubbleView <span class="token punctuation">:</span> <span class="token builtin">BubbleView</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> currentBounds <span class="token operator">=</span> view <span class="token punctuation">.</span> bounds <span class="token builtin">UIView</span> <span class="token punctuation">.</span> <span class="token function">animate</span> <span class="token punctuation">(</span> withDuration <span class="token punctuation">:</span> <span class="token number">1.5</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> frame <span class="token operator">=</span> bubbleView <span class="token punctuation">.</span> frame frame <span class="token punctuation">.</span> origin <span class="token punctuation">.</span> y <span class="token operator">=</span> currentBounds <span class="token punctuation">.</span> height bubbleView <span class="token punctuation">.</span> frame <span class="token operator">=</span> frame <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
That’s it, above is an example of a delegation – handling events that touch the user’s view, by delegating the logic to the controller.
Hopefully, you will understand and feel comfortable using Delegate Pattern
. The first article has many shortcomings, hope everyone helps.
Source: https://dev.to/mrcflorian/delegation-pattern-in-swift-by-example-30g3