Mastering SwiftUI: Building Beautiful and Interactive User Interfaces: Part 2
Level up your SwiftUI skills
Hola! welcome back fellow SwiftUI explorers! đ In the first part of our SwiftUI series, âSetting the Foundation,â we embarked on an incredible journey, discovering the essence of SwiftUI, its advantages, and even how to set up a SwiftUI project in Xcode and along with that we explored swiftUI life cycle and basic ! If you missed it, donât worry â you can catch up right here!
Now, fasten your seat belts, SwiftUI enthusiasts! đ⨠The thrilling ride continues as we embark on the second part of our epic SwiftUI series. In this exhilarating instalment, weâre about to push the boundaries and explore the captivating world of SwiftUIâs animations, layouts, and user interactions.
In todays Blog we will discuss on the following points:
- SwiftUI Layouts
- Understanding Stacks
- Z Index
- Hands-On Implementation with Stacks
- Custom Frame for SwiftUI views
- Lists
- Navigation Stacks
SwiftUI Layouts
SwiftUI layout refers to the process of arranging and organizing views within your appâs user interface. SwiftUI provides a declarative and flexible approach to define how user interface elements should be positioned, sized, and aligned on the screen. The layout system in SwiftUI enables you to create visually appealing and responsive user interfaces that adapt to various screen sizes, orientations, and environments.
In SwiftUI, you build layouts using a hierarchy of view containers, such as VStack, HStack, ZStack, and List, among others. These containers are known as âstacksâ and are the building blocks of SwiftUI layouts. Each stack arranges its child views in a specific direction, such as vertically (VStack), horizontally (HStack), or overlapping in a three-dimensional space (ZStack).
Understanding Stacks
Stacks play a vital role in arranging and organising views within your user interface, allowing you to structure your UI elements in a structured and efficient manner.
VStack â Vertical Stack: It arranges its child views in a top-to-bottom sequence. This means that views added to VStack will be stacked vertically, with one view on top of another.
struct ContentView: View {
ZStack {
Text("Hello")
Text("SwiftUI")
Text("Enthusiast")
}
}
You will get this output on your app
HStack â Horizontal Stack: It aligns its child views in a left-to-right sequence. When views are added to HStack, they will be positioned next to each other horizontally.
struct ContentView: View {
HStack {
Text("Hello")
Text("SwiftUI")
Text("Enthusiast")
}
}
For the above code you will get this output on your app:
ZStack â Z-Axis Stack: It overlays views on top of one another in a three-dimensional arrangement. This unique feature allows you to create visually engaging user interfaces by layering views with different visual elements.
Lets try add some text over an image using ZStack
struct ContentView: View {
var body: some View {
ZStack {
Image("bulb")
Text("Its a bulb")
.font(.largeTitle)
.background(.black)
.foregroundStyle(.white)
}
}
}
Nesting Stacks for Complex Layouts: One of the strengths of SwiftUI is its ability to nest stacks inside one another, enabling you to create sophisticated layouts with varying levels of hierarchy. We can nest VStack, HStack and ZStack as per our requirement.
Z Index
In SwiftUI, the zIndex
modifier is used to control the stacking order of views within a container. It allows you to adjust the rendering order of views, so that some views appear in front of others.
The zIndex
modifier takes an integer value, and views with higher zIndex
values will be rendered on top of views with lower zIndex
values. By default, views have a zIndex
of 0.
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Color.red
.frame(width: 200, height: 200)
Color.blue
.frame(width: 150, height: 150)
.zIndex(1)
Color.green
.frame(width: 100, height: 100)
.zIndex(2)
}
}
}
Weâll get this:
As we didnât give zIndex to red container it assume zIndex value 0
thats why it is at the bottom of ZStack, on top of it is blue container as it zIndex value is 1
and above all we have green container as it has highest zIndex value among all the containers i.e., 2
.
Hands-On Implementation with Stacks
Now that we have explored the theory behind SwiftUI layouts and stacks, itâs time to roll up our sleeves and dive into real-world implementation! In this hands-on section, we will unleash the power of SwiftUI stacks and learn how to use them to create beautiful and dynamic user interfaces.
In my last article we already see how to setup a swiftUI project, so lets start. Our goal is to learn about how to use Stacks and nesting Stacks for Complex Layouts. For that lets do a small project.
Lets create a profile card with a blue background and an image of âModabbir Tariqueâ in a circular frame. The name and designation are displayed below the image. The contact details are organised in a horizontal stack, with labels on the left and corresponding information on the right.
To achieve that we have make ZStack whose background colour is blue, and inside that ZStack we have to make VStack where we insert image, user name and user designation. Apart from that we make HStack inside it we have two ZStack one contain email, location and phone header and another contains there respective values.
Lets see the code and final output now.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
ZStack {
Color.blue
.frame(height: 180)
.cornerRadius(20)
VStack {
Image("profile_pic")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.clipShape(Circle())
.padding(.top, 5)
Text("Modabbir Tarique")
.font(.title)
.foregroundColor(.white)
.padding(.top, 0)
Text("iOS Developer")
.font(.subheadline)
.foregroundColor(.white)
.padding(.top, 0)
}
}
HStack {
VStack(alignment: .leading, spacing: 10) {
Text("Email:")
Text("Location:")
Text("Phone:")
}
VStack(alignment: .leading, spacing: 10) {
Text("modabbir@gmail.com")
Text("Bengaluru, India")
Text("+91 9234567890")
}
}
.padding(.top, 20)
.padding(.horizontal, 20)
}
.padding(.horizontal, 20)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
O/P:
You can use your own profile picture and other information like name, mobile number, location.
âThis ainât my digits youâre looking for!â đ
Custom Frame for SwiftUI views
By default SwiftUIâs views take up only as much space as they need, but if you want that to change you can use a frame()
modifier. The frame
modifier allows you to set the size and position of a view within its parent container.
The basic syntax for the frame
modifier is as follows:
.frame(width: desiredWidth, height: desiredHeight)
You can adjust the desiredWidth
and desiredHeight
parameters to set the width and height of the view, respectively according to your requirement.
import SwiftUI
struct ContentView: View {
var body: some View {
Rectangle() // Replace this with your desired view
.fill(Color.blue)
.frame(width: 100, height: 100) // Set your custom width and height here
}
}
You will get something like this:
But, if you donât use frame then you will get this:
If you want to o set the position of the view within its parent container using the alignment
parameter.
struct ContentView: View {
var body: some View {
Rectangle() // Replace this with your desired view
.fill(Color.blue)
.frame(width: 200, height: 100, alignment: .topLeading) // Set your custom width, height, and alignment here
}
}
Note: The frame
modifier is just one of many ways to control the size and position of views in SwiftUI. You can also use layout guides, alignment guides, and other modifiers like padding
and offset
to achieve more complex layouts and positioning.
Lists
A list view is a container view that shows its content in a single scrollable column. This list can be constructed using hierarchical, dynamic, and static data. It provides a great-looking appearance that conforms to the standard styling for each of the different Apple platforms.
We have the following advantages of using the List view in SwiftUI are:
- Dynamic content handling.
- Excellent performance with large lists.
- Automatic cell recycling for memory optimisation.
- Seamless data binding for easy updates.
- Built-in accessibility support.
- Native look and feel for platform consistency.
- Customisable appearance for individualisation.
- Integration with navigation for hierarchical flows.
You can add list inside the swiftUI view like this:
List{
Text("item1")
Text("item2")
Text("item3")
}
This is a static list view â weâre sending in three pieces of fixed data, so it interprets them as three rows in the table.
We will discuss more about lists in part 3.
Navigation Stacks
NavigationStack (also known as NavigationView) is a container view that manages a hierarchical navigation flow in your app. It allows you to push and pop views onto and off the navigation stack, creating a navigation hierarchy. The NavigationStack is typically used to implement navigation patterns like master-detail interfaces and drill-down navigation.
Properties:
- NavigationLink: Inside the NavigationStack, we can use NavigationLink to create clickable elements (such as buttons or list items) that trigger navigation to another view. When a user taps on a NavigationLink, SwiftUI automatically pushes the destination view onto the navigation stack.
- NavigationTitle: You can set a navigation title for each view that appears on the navigation stack. This title will be displayed at the top of the screen when the view is shown. You can set the title using the
navigationTitle
modifier. - Navigation Back Button: When you push a new view onto the navigation stack, SwiftUI automatically adds a back button to the navigation bar to navigate back to the previous view.
- Navigation Bar Customisation: SwiftUI allows you to customize the navigation bar appearance using the
navigationBarTitleDisplayMode
modifier and thenavigationBarItems
modifier. You can add buttons to the navigation bar, change the title display mode, and more.
Lets do a small project where ContentView contains a list with two NavigationLinks. When you tap on a link, it will push the corresponding DetailView onto the navigation stack, and the DetailView will show the provided text with its own navigation title.
Create a new project in Xcode while choosing the options for your new project select SwiftUI option for the interface.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink("Detail View 1", destination: DetailView(text: "Detail View 1"))
NavigationLink("Detail View 2", destination: DetailView(text: "Detail View 2"))
}
.navigationTitle("Main View")
}
}
}
struct DetailView: View {
let text: String
var body: some View {
Text(text)
.navigationTitle("Detail")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
When we run the code, weâre greeted with an intuitive user interface. The Main View presents a list with two options: âDetail View 1â and âDetail View 2â. Upon tapping any of these options, we smoothly transition to the corresponding DetailView, where we see the custom text displayed with a navigation title.
Feel free to copy and paste the code into your Xcode playground or project to see the magic of SwiftUI Lists and Navigation firsthand. Experiment with different texts, add more items to the list, or even create your custom DetailViews with unique content.
In conclusion, SwiftUIâs Stacks and layout system offer a powerful and intuitive way to build user interfaces, providing flexibility and responsiveness to different screen sizes and orientations. In this article, we focused on the basics of using Stacks and explored how to create static lists, and navigation Stack.
In the next part of our series, we will delve deeper into SwiftUIâs List view, expanding our knowledge to cover dynamic element lists. We will learn how to handle data from various sources and display it in a way that adapts to changes seamlessly. Additionally, we will explore more advanced concepts such as custom cells, allowing us to personalize the appearance of list items to meet specific design requirements.
Furthermore, we will discuss the Scroll view, a crucial component that enables us to create scrollable content, ideal for displaying large datasets or content that exceeds the available screen space. Weâll understand how to use it effectively to enhance the user experience and make our app more user-friendly.
With these essential concepts under our belt, we will be well-equipped to create sophisticated and interactive user interfaces with SwiftUI. So, stay tuned for the next article, where we will continue our exciting journey into the world of SwiftUI Lists and Scroll views. Happy coding!
Check out the next part of the series: SwiftUI â Part3
Feel free to connect me on LinkedIn
Thanks for reading!