How Live Rendering works
Live Rendering allows to setup custom properties for interface elements and see results immediately in interface builder.
Live Rendering allows to setup custom properties for interface elements and see results immediatly in interface builder. Let's create custom view with possibility to setup border color, border width and corner radius with Interface Builder. For this purpose let's create custom class CustomView and inherit it from UIView.
For Live Rendering annotate class with
@IBDesignable and for setup properties add
@IBInspectable annotation.
import Foundation
import UIKit
@IBDesignable
class CustomView: UIView {
@IBInspectable
var borderColor: UIColor? {
didSet {
self.layer.borderColor = borderColor?.cgColor
}
}
@IBInspectable
var borderWidth: CGFloat = 0 {
didSet {
self.layer.borderWidth = borderWidth
}
}
@IBInspectable
var cornerRadius: CGFloat = 0 {
didSet {
self.layer.cornerRadius = cornerRadius
self.layer.masksToBounds = (cornerRadius > 0)
}
}
}
Custom View with custom properties
Class of UIView must be set to CustomView
We can define maskToBounds property depends on cornerRadius.
@IBInspectable
var cornerRadius: CGFloat = 0 {
didSet {
self.layer.cornerRadius = cornerRadius
self.layer.masksToBounds = (cornerRadius > 0)
}
}
Or we can move it to separate @Inspectable property.
@IBInspectable
var maskToBounds: Bool = false {
didSet {
self.layer.masksToBounds = maskToBounds
}
}
import Foundation
import UIKit
@IBDesignable
class CustomView: UIView {
@IBInspectable
var borderColor: UIColor? {
didSet {
self.layer.borderColor = borderColor?.cgColor
}
}
@IBInspectable
var borderWidth: CGFloat = 0 {
didSet {
self.layer.borderWidth = borderWidth
}
}
@IBInspectable
var cornerRadius: CGFloat = 0 {
didSet {
self.layer.cornerRadius = cornerRadius
}
}
@IBInspectable
var maskToBounds: Bool = false {
didSet {
self.layer.masksToBounds = maskToBounds
}
}
}
When maskToBounds property is set to false then inner view is overlap superview.
When maskToBounds property set to true.
But we can make this properties available for all views in project. So let's create Extension fot UIView and move to it all inspectable properties.
import Foundation
import UIKit
extension UIView {
@IBInspectable
var borderColor: UIColor? {
set {
self.layer.borderColor = newValue?.cgColor
}
get {
if let color = self.layer.borderColor {
return UIColor(cgColor: color)
}
return nil
}
}
@IBInspectable
var borderWidth: CGFloat {
set {
self.layer.borderWidth = newValue
}
get {
return self.layer.borderWidth
}
}
@IBInspectable
var cornerRadius: CGFloat {
set {
self.layer.cornerRadius = newValue
}
get {
return self.layer.cornerRadius
}
}
@IBInspectable
var maskToBounds: Bool {
set {
self.layer.masksToBounds = newValue
}
get {
return self.layer.masksToBounds
}
}
}
And remove all properties from CustomView class. But left @IBDesignable annotation for Live Rendering.
import Foundation
import UIKit
@IBDesignable
class CustomView: UIView {
}
Let's go forward and add properties for displaying shadow.
import Foundation
import UIKit
extension UIView {
@IBInspectable
var borderColor: UIColor? {
set {
self.layer.borderColor = newValue?.cgColor
}
get {
if let color = self.layer.borderColor {
return UIColor(cgColor: color)
}
return nil
}
}
@IBInspectable
var borderWidth: CGFloat {
set {
self.layer.borderWidth = newValue
}
get {
return self.layer.borderWidth
}
}
@IBInspectable
var cornerRadius: CGFloat {
set {
self.layer.cornerRadius = newValue
}
get {
return self.layer.cornerRadius
}
}
@IBInspectable
var maskToBounds: Bool {
set {
self.layer.masksToBounds = newValue
}
get {
return self.layer.masksToBounds
}
}
@IBInspectable
var shadowColor: UIColor? {
set {
self.layer.shadowColor = newValue?.cgColor
}
get {
if let color = self.layer.shadowColor {
return UIColor(cgColor: color)
}
return nil
}
}
@IBInspectable
var shadowRadius: CGFloat {
set {
self.layer.shadowRadius = newValue
}
get {
return self.layer.shadowRadius
}
}
@IBInspectable
var shadowOffset: CGSize {
set {
self.layer.shadowOffset = newValue
}
get {
return self.layer.shadowOffset
}
}
@IBInspectable
var shadowOpacity: Float {
set {
self.layer.shadowOpacity = newValue
}
get {
return self.layer.shadowOpacity
}
}
}
UIView with shadow. Now we can set shadow from Interface Builder.
If we want to create custom inspectable enumerated property.
import Foundation
import UIKit
enum ViewStyle: String {
case Rounded = "rounded"
case Shadowed = "shadowed"
var maskToBounds: Bool {
switch self {
case .Rounded: return true
case .Shadowed: return false
}
}
var cornerRadius: CGFloat {
return 6
}
var borderWidth: CGFloat {
return 2
}
var borderColor: UIColor {
return UIColor.black
}
var shadowColor: UIColor{
return UIColor.black
}
var shadowRadius: CGFloat {
return 5.0
}
var shadowOffset: CGSize {
return CGSize(width: 5.0, height: 5.0)
}
var shadowOpacity: Float {
return 1.0
}
}
Add this property to UIView Extension.
import Foundation
import UIKit
extension UIView {
.....
@IBInspectable
var viewStyle: String? {
set {
self.configureWithStyle(viewStyle: newValue)
}
get {
return nil
}
}
private func configureWithStyle(viewStyle: String?) {
if let viewStyleStr = viewStyle {
if let styleEnum = ViewStyle(rawValue: viewStyleStr) {
self.borderColor = styleEnum.borderColor
self.borderWidth = styleEnum.borderWidth
self.cornerRadius = styleEnum.cornerRadius
self.maskToBounds = styleEnum.maskToBounds
self.shadowOpacity = styleEnum.shadowOpacity
self.shadowOffset = styleEnum.shadowOffset
self.shadowRadius = styleEnum.shadowRadius
self.shadowColor = styleEnum.shadowColor
}
}
}
}
UIView with style "rounded"
UIView with style "shadowed"
Running on the device
GitHub Link
No comments:
Post a Comment