Getting to know SwiftUI – part 1

Learning Swift – Day 208

Life recap of these days!

My birthday’s just passed and I took a day (and a half) off.

I also got my first contact with a company with whom I could work in the future but they are not looking for any part-time applicant and, also, they are looking for someone now, which I just cannot do. I will contact them in April to make the test and see how it goes.

In the meantime I have talked with some people who have either worked very recently in the industry or have been employers in the industry very recently in Italy. Sadly, it seems that the wage for a Junior Developer is about 1.250,00 EUR per month (net). That makes exactly: 16.250,00 EUR per year. If you want to live alone with that wage in Italy it just IS NOT POSSIBLE! No way! Ever!

Sure, Senior iOS gets almost double that but then let’s be clear that Junior positions is for freshly graduated people who are still living with their parents and, therefore, have no real-life expense! I mean … I really expected something more than this and I am really happy I have not made any serious commitment to leaving my actual work in music! First, I love my engraving job. Second, if I have to take a leap and get something else, I need something that makes me earn MORE than before, not LESS! This is just crazy!

Right now I have so many ideas bouncing in my head, will try to put order in them while I study new things and enjoy it!

100 Days of SwiftUI – Day 23

Project 3, part 1

This is the first technique project of the series and we will delve into what views are and how they work, alongside some deep explanation on modifiers.

Views and modifiers: Introduction

Create a Single View App called ViewsAndModifiers.

Let’s reflect on why we use structs and not classes for our views in SwiftUI.

The first reason is simply a performance one: not having inheritance to worry about, every SwiftUI view is very light and fast to create. The second reason is that having structs forces us to think about the current state of our app.

Classes could change their value freely, while structs cannot. Views in SwiftUI are constants so they cannot change their value over time. We need therefore to think in a more functional way than before.

In the end Paul says that if we use a class for a view it will likely crash … wait … only for SwiftUI, right?!

What is behind the main SwiftUI view?

When we apply a modifier to the Text we get in our ContentView, only the frame of the label gets coloured. Paul specifies that, for SwiftUI developers, there is nothing behind a view. He also warns that we shouldn’t try to change the colour of the view but I ask … why?! In UIKit I can just call view.backgroundColor = .red and it will just work… I now, my second name is Mr. Skeptical!

SwiftUI views are controlled by a UIHostingController, which is what bridges between UIKit and SwiftUI… so, wait, is SwiftUI just a shiny and sparkling wrapper over UIKit? Same as Swift is bridging many things over Objective-C?! Getting suspicious over here… I don’t know how you feel, but I feel personally horrified by the definition of UIHostingController:

class UIHostingController<Content> : UIViewController where Content : View

First of all, it is a generic class that, when instantiated, creates a Content type that conforms to the View protocol. Thing is … all this inherits from UIViewController so all what was said before is what, smoke?! If the class just about our views is a subclass of UIViewController we are point blank from the beginning! The feeling is really strange…

Paul explains that we should get used to expand our views instead of trying to colour what is behind them (which should effectively be perceived as nothing!). To do so we should adjust the .frame(maxWidth:maxHeight:) modifier on our Text so that the arguments passed into it are .infinity, which corresponds to the mathematical value of +∞! To understand more, here is the Documentation for this modifier (actually this is the one I clicked by mistake, frame(width:height:alignment:):

Summary

Positions this view within an invisible frame with the specified size.

Declaration

Discussion

Use this method to specify a fixed size for a view’s width, height, or both. If you only specify one of the dimensions, the resulting view assumes this view’s sizing behaviour in the other dimension.

For example, the first ellipse in the following code is rendered in a fixed 200 by 100 frame. The second ellipse has only its height fixed, at 100; its width still expands to fill its parent’s dimensions.

If this view is smaller than the resulting frame in either dimension, alignment specifies this view’s alignment within the frame.

Parameters

width: a fixed width for the resulting view. If width is nil, the resulting view assumes this view’s sizing behaviour.

height: a fixed height for the resulting view. If height is nil, the resulting view assumes this view’s sizing behaviour.

alignment: the alignment of this view inside the resulting view. alignment applies if this view is smaller than the size given by the resulting frame.

Returns

A view with fixed dimensions of width and height, for the parameters that are non-nil.

I took the liberty to correct a couple of syntax mistakes Apple had left in there.

The one we are looking for is this massive beast:

Summary

Positions this view within an invisible frame with the specified width and height constraints.

Declaration

Discussion

Always specify at least one size characteristic when calling this method. Pass nil or leave out a characteristic to indicate that the frame should adopt this view’s sizing behaviour, constrained by the other non-nil arguments.

The size proposed to this view is the size proposed to the frame, limited by any constraints specified, and with any ideal dimensions specified replacing corresponding nil dimensions in the proposal.

If no minimum or maximum constraint is specified in a given dimension, the frame adopts the sizing behaviour of its child in that dimension. If both constraints are specified in a dimension, the frame unconditionally adopts the size proposed for it, clamped to the constraints. In detail, the size of the frame in either dimension is:

Parameters

minWidth: The minimum width of the resulting frame.

idealWidth: The ideal width of the resulting frame.

maxWidth: The maximum width of the resulting frame.

minHeight: The minimum height of the resulting frame.

idealHeight: The ideal height of the resulting frame.

maxHeight: The maximum height of the resulting frame.

alignment: The alignment of this view inside the resulting frame. Note that most alignment values have no apparent effect when the size of the frame happens to match that of this view.

Returns

A view with flexible dimensions given by the call’s non-nil parameters.

Long story short, this means that if we use maxWidth and maxHeight the view can fill the whole space available, but it is not forced to do so. Look at some of the options for those parameters, their names are quite funny:

Using .infinity will make the view expand to cover all available space, until it is reclaimed by someone else, but it will not go beyond the Safe Area, as to do that you need to use the edgesIgnoringSafeArea(.all) modifier. This is fascinating:

Summary

Extends the view out of the safe area on the specified edges.

Declaration

Parameters

edges: The set of the edges on which to ignore the safe area.

Returns

A view that extends this view out of the safe area on the edges specified by edges.

If we then click on Edge we learn that it is an enum, with raw values of type Int8 to reduce the amount of memory consumed and of which, Set is a structure inside of it with all the type properties we need! It conforms to the OptionSet protocol, which manages a lot of things related to Sets.

Anyway, here is what we get with all this:

Now, that's red!
Now, that’s red!

I will stop here as it is already 11pm and tomorrow I have the usual crazy Friday ahead of me. Also, I want to keep these articles shorter. Let me know if you find them clearer or not!

Good night, Swifty world!


Thank you for reading!

If you like what I’m doing here please consider liking this article and sharing it with some of your peers. If you are feeling like being really awesome, please consider making a small donation to support my studies and my writing (please appreciate that I am not using advertisement on my articles).

If you are interested in my music publications don’t forget visit my Facebook page and the pages where I publish my scores (Gumroad, SheetMusicPlus e ScoreExchange).

You can also support me by buying Paul Hudson’s book from this Affiliate Link.

Anyways, thank you so much for reading!

Till the next one!

Published by Michele Galvagno

Professional Musical Scores Designer and Engraver Graduated Classical Musician (cello) and Teacher Tech Enthusiast and Apprentice iOS / macOS Developer Grafico di Partiture Musicali Professionista Musicista classico diplomato (violoncello) ed insegnante Appassionato di tecnologia ed apprendista Sviluppatore iOS / macOS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with WordPress.com
Get started
%d bloggers like this: