Interface Builder Live Views and iOS 10 Embedded Frameworks
Previous | Table of Contents | Next |
Drawing iOS 10 2D Graphics in Swift with Core Graphics | An iOS 10 2D Graphics Tutorial using Core Graphics and Core Image |
Learn SwiftUI and take your iOS Development to the Next Level |
Two related areas of iOS development will be covered in this chapter in the form of Live Views in Interface Builder and Embedded Frameworks, both of which are designed to make the tasks of sharing common code between projects and designing dynamic user interfaces easier.
Embedded Frameworks
A framework is defined by Apple as “a collection of code and resources to encapsulate functionality that is valuable across multiple projects”. A typical iOS application project will use a multitude of Frameworks from the iOS SDK. All applications, for example, make use of the Foundation Framework while a game might also make use of the SpriteKit Framework.
Embedded Frameworks allow developers to create their own frameworks. Embedded frameworks are easy to create and provide a number of advantages, the most obvious of which is the ability to share common code between multiple application projects.
Embedded Frameworks are particularly useful when working with extensions. By nature, an extension will inevitably need to share code that already exists within the containing app. Rather than duplicate code between the app and the extension, a better solution is to place common code into an embedded framework.
Another benefit of embedded frameworks is the ability to publish code in the form of 3rd party frameworks that can be downloaded for use by other developers in their own projects.
One of the more intriguing features of embedded frameworks, however, is that they facilitate a powerful feature of Interface Builder known as Live Views.
Learn SwiftUI and take your iOS Development to the Next Level |
Interface Builder Live Views
Traditionally, designing a user interface layout using Interface Builder has involved placing static representations of view components onto a canvas. The application logic behind these views to implement dynamic behavior is then implemented within the view controller and the application compiled and run on a device or simulator in order to see the live user interface is action.
Live views allow the dynamic code behind the views to be executed from within the Interface Builder storyboard file as the user interface is being designed without the necessity to compile and run the application.
Live views also allow variables within the code behind a view to be exposed in such a way that they can be accessed and modified in the Interface Builder Attributes Inspector panel, with the changes reflected in real-time within the live view.
The reason that embedded frameworks and live views are both covered in this chapter is that a prerequisite for live views is for the underlying code for a live view to be contained within an embedded framework. The best way to gain a better understanding of both embedded frameworks and live views is to see them in action in an example project.
Creating the Example Project
Launch Xcode and create a new Single View Application project named LiveViewDemo using Swift as the programming language and with the device family menu set to Universal.
When the project has been created, select the Main.storyboard file and drag and drop a View object from the Object Library panel onto the view controller canvas. Resize the view, stretching it in each dimension until the blue dotted line appears indicating the recommended margin. Display the Auto Layout Add New Constraints menu and enable “spacing to nearest neighbor” constraints on all four sides of the view with the Constrain to margins option enabled as shown in Figure 62-1 before clicking on the Add 4 Constraints button:
Figure 62-1
Once the above steps are complete, the layout should resemble that illustrated in Figure 62-2 below:
Learn SwiftUI and take your iOS Development to the Next Level |
Figure 62-2
With the user interface designed, the next step is to add a framework to the project.
Adding an Embedded Framework
The framework to be added to the project will contain a UIView subclass containing some graphics drawing code.
Within Xcode, select the File -> New -> Target… menu option and, in the template selection panel, scroll to and select the Cocoa Touch Framework template (Figure 62-3):
Figure 62-3
Click on the Next button and, on the subsequent screen, enter MyDrawKit into the product name field before clicking on the Finish button.
Within the project navigator panel, a new folder will have been added named MyDrawKit into which will be stored the files that make up the new framework. Ctrl-click on this entry and select the New File… menu option. In the template chooser panel, select Cocoa Touch Class before clicking on Next.
On the next screen, name the class MyDrawView and configure it as a subclass of UIView. Click the Next button and save the new class file into the MyDrawKit subfolder of the project directory.
Select the Main.storyboard file in the project navigator panel and click on the View object that was added in the previous section. Display the Identity Inspector in the utilities panel and change the Class setting from UIView to MyDrawView:
Figure 62-4
Learn SwiftUI and take your iOS Development to the Next Level |
Implementing the Drawing Code in the Framework
The code to perform the graphics drawing on the View will reside in the MyDrawView.swift file which is located in the MyDrawKit folder. Locate this file in the project navigator panel and double-click on it to load it into a separate editing window (thereby allowing the Main.storyboard file to remain visible in Interface Builder).
Remove the comment markers (/* and */) from around the template draw method and implement the code for this method so that it reads as follows:
<pre? import UIKit import QuartzCore
class MyDrawView: UIView {
var startColor: UIColor = UIColor.white var endColor: UIColor = UIColor.blue var endRadius: CGFloat = 100
override func draw(_ rect: CGRect) { let context = UIGraphicsGetCurrentContext()
let colorspace = CGColorSpaceCreateDeviceRGB() let locations: [CGFloat] = [ 0.0, 1.0]
let gradient = CGGradient(colorsSpace: colorspace, colors: [startColor.cgColor, endColor.cgColor] as CFArray, locations: locations)
var startPoint = CGPoint() var endPoint = CGPoint()
let startRadius: CGFloat = 0
startPoint.x = 210 startPoint.y = 180 endPoint.x = 210 endPoint.y = 200
context?.drawRadialGradient (gradient!, startCenter: startPoint, startRadius: startRadius, endCenter: endPoint, endRadius: endRadius,
options: .drawsBeforeStartLocation)
}
} </pre>
Making the View Designable
At this point the code has been added and running the application on a device or simulator will show the view with the graphics drawn on it. The object of this chapter, however, is to avoid the need to compile and run the application to see the results of the code. In order to make the view “live” within Interface Builder, the class needs to be declared as being “Interface Builder designable”. This is achieved by adding an @IBDesignable directive immediately before the class declaration in the MyDrawView.swift file:
import UIKit import QuartzCore @IBDesignable class MyDrawView: UIView { var startColor: UIColor = UIColor.white var endColor: UIColor = UIColor.blue var endRadius: CGFloat = 100 . . . }
Learn SwiftUI and take your iOS Development to the Next Level |
Figure 62-5
From now on, any changes made to the MyDrawView code will be reflected in the Interface Builder live view. To see this in action, change the endColor variable declaration so that it is assigned a different color and observe the color change take effect in the Interface Builder live view:
var endColor: UIColor = UIColor.red
Making Variables Inspectable
Although it is possible to modify variables by editing the code in the framework class, it would be easier if they could be changed just like any other property using the Attributes Inspector panel. In fact, this can be achieved simply by prefixing the variable declarations with the @IBInspectable directive as follows:
@IBDesignable class MyDrawView: UIView { @IBInspectable var startColor: UIColor = UIColor.white @IBInspectable var endColor: UIColor = UIColor.red @IBInspectable var endRadius: CGFloat = 100 . . . }
With the changes made to the code, select the View in the storyboard file and display the Attributes Inspector panel. The properties should now be listed for the view (Figure 62-6) and can be modified. Any changes to these variables made through the Attributes Inspector will take effect in real-time without the need for Xcode to recompile the framework code. These settings will also be generated into the application when it is compiled and run on a device or simulator.
Figure 62-6
Summary
This chapter has introduced two concepts in the form of embedded frameworks and Interface Builder live views. Embedded frameworks allow developers to place source code into frameworks which can then be shared between multiple application projects. Embedded frameworks also provide the basis for the live views feature of Interface Builder. Prior to the introduction of live views, it was necessary to compile and run an application in order to be able to see dynamic user interface behavior in action. With live views, the dynamic behavior of a view can now be seen within Interface Builder, with code changes reflected in real-time.
Learn SwiftUI and take your iOS Development to the Next Level |
Previous | Table of Contents | Next |
Drawing iOS 10 2D Graphics in Swift with Core Graphics | An iOS 10 2D Graphics Tutorial using Core Graphics and Core Image |