Leave a rating/review
I think the best way to practice using SwiftUI modifiers to try things. So, I’ve got a challenge to help you do that.
In the starter project, you’ll find Challenge 1 and Challenge 2 dot swift files with a bit of code already included. See if you can get the top preview to match the bottom one by editing the body in each file.
You’ll need to explore the library to find some new modifiers! The attributes inspector might also help you out.
I don’t want you to fret about measuring to get frame sizes exactly right. Just get as close as you can.
Two things to remember: The order of modifiers matters! And, a VStack is also a View that you can modify.
Ok. Pause the video, give it a try, and then meet me back here to go through it.
Have fun!
Challenge 1
Ok! Challenge 1.
I’ve got a giant monster and I need to turn it into this more reasonably-sized monster.
This is an image, so I’ll start by making it resizable.
Image("monster")
.resizable()
I know I have to do that first, because it’s specific to the Image type.
And then I could specify a frame size and if you did that, that’s fine. But there is another pair of modifiers that let you scale an image to either fill up or fit within their parent.
.scaledToFit()
Next, there is this green outline, or border, around the image.
- I’ll look that one up in the library.
- There is a border modifier!
- So I’ll add that…
And then change the color to green and the width to 5.
.border(Color.green, width: 5)
There’s also a sort of dropshadow going on here, behind the monster.
If you searched for a “shadow” in the library, you’d find this modifier!
.shadow(radius: 15)
And then, it looks like there is some space all around the whole thing.
That means padding.
.padding()
This almost looks right. But it looks like the shadow should only be applied to the monster, and not the border, too.
I can fix that by moving the shadow up before the border is added.
.shadow(radius: 15)
.border(Color.green, width: 5)
Lookin pretty good. Onto challenge 2!
Challenge 2
This one has a bit more going on.
First, I know I need another Text element, here, underneath “Sunny”
Text("H: 61° L: 44°")
And then this top bit of text is larger and bolder. The attributes inspector can help me out, here.
I can change the font weight to Semibold…
.fontWeight(.semibold)
And then to make it bigger,
- this Font drop down will give me all of the system’s presets for text sizes.
- I’ll go with “title”
.font(.title)
I can also change the color to “White” from here!
.foregroundColor(.white)
You could have also found all of those modifiers hanging out in the text section of the library.
Now, the text below should also be white…
.foregroundColor(.white)
Or, whitish. I could make a custom gray color with a Color initalizer.
But I can also modify the opacity
.opacity(0.7)
The text is all looking good, but there’s more to do!
This image, for example, is the wrong color.
If you used the foreground color modifier on this, that would work fine.
But I did leave this “renderingMode” here for a reason. This sun is one of the “multicolor” SFSymbols. So, if you change the rendering mode to Original…
.renderingMode(.original)
It uses the built-in color instead of treating it like all of the regular SFSymbols.
The sun is also a little small. Rendering mode returns an image, so, I can use resizable right after it.
.resizable()
And then I’ll set a little square frame for this one.
.frame(width: 50, height: 50)
All of the bits and pieces are right, now I’ve just got to get this background to look right.
To get these rounded corners, there’s a corner radius modifier
.cornerRadius(12.0)
- That does need to go after the background is applied, otherwise you won’t see the nice corners!
It still looks like I need some padding, though.
.padding()
- That I actually want before the background so that all that space is filled in with the gradient.
Speaking of the gradient, the example has the white coming in from the upper left corner.
The attributes inspector makes it easy for me to adjust the start and end points of the gradient to match…
startPoint: .topLeading, endPoint: .bottomTrailing
Aaannnd that’s looking pretty close! We’re done here.