- iOS Programming Cookbook
- Hossam Ghareeb
- 547字
- 2021-07-09 18:29:47
There's more...
We saw how to add UIViews using interface builder or programmatically. These are the most commonly used ways in UIViews while working on an iOS app. In some cases, native components don't fit your needs, and you have to build your own custom UIView. Let's see in action how to build a custom UIView. In the following example, we will see how to build a circular progress bar programmatically and how to use or customize it using interface builder.
Go to Xcode and create a new Swift class CircularProgressBar, which extends UIView. Then, add the following code:
@IBDesignable
class CircularProgressBar: UIView {
/// The background fixed color of progress bar
@IBInspectable var progressFixedColor : UIColor = UIColor.whiteColor()
/// The progressive color
@IBInspectable var progressColor : UIColor = UIColor.redColor()
/// The line width of the progress circle
@IBInspectable var lineWidth:CGFloat = 5.0
/// The layer where we draw the progressive animation.
private var progressiveLayer : CAShapeLayer?
func updateProgess(progress:CGFloat, animated:Bool,
duration:CFTimeInterval){
if self.progressiveLayer == nil{
self.setNeedsDisplay()
}
if progress <= 1.0{
self.progressiveLayer?.strokeEnd = progress
if animated {
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "strokeEnd");
animation.duration = duration
animation.fromValue = NSNumber(float: 0.0)
animation.toValue = NSNumber(float: Float(progress));
animation.timingFunction = CAMediaTimingFunction(name:
kCAMediaTimingFunctionEaseInEaseOut)
self.progressiveLayer?.addAnimation(animation, forKey:
"animateStrokeEnd")
CATransaction.commit()
}
}
}
override func drawRect(rect: CGRect) {
// Drawing code
let fixedLayer = getShapeLayerForRect(rect, strokeColor:
progressFixedColor)
fixedLayer.strokeEnd = 1.0
self.layer.addSublayer(fixedLayer)
let progressiveLayer = getShapeLayerForRect(rect, strokeColor:
progressColor)
progressiveLayer.strokeEnd = 0.0
self.progressiveLayer = progressiveLayer
self.layer.addSublayer(progressiveLayer)
}
private func getShapeLayerForRect(rect:CGRect, strokeColor
sColor:UIColor) -> CAShapeLayer{
let radius = CGRectGetWidth(rect) / 2 - lineWidth / 2
let newRect = CGRectMake(lineWidth / 2, lineWidth / 2, radius * 2,
radius * 2)
let path = UIBezierPath(roundedRect: newRect, cornerRadius:
radius).CGPath
let shape = CAShapeLayer()
shape.path = path
shape.strokeColor = sColor.CGColor
shape.lineWidth = self.lineWidth
shape.fillColor = nil
return shape
}
}
Let's explain the code step by step:
- We marked our class with @IBDesignable, which tells the compiler that this class is a custom UIView that can be rendered in interface builder. This helps you to see what the view looks like without running the on simulator or device.
- We listed three parameters to set the colors and line width of the progress view. Each parameter is marked as @IBInspectable, which tells the compiler to display these parameters in Attribute Inspector, so you customize these values as well from interface builder.
- Go to interface builder and add a UIView as a subview to the view that is blue. Change its class from UIView to CircularProgressBar from the Identity Inspector tab. Change its background color to clear color and see how the view will be rendered:
- Also, if you open the Attribute Inspector, you will see that three additional attributes have been added:
- Then, we override the drawRect method. This function should be overridden to make a custom drawing in your view. In drawRect, we created two circular shapes. One shape is the fixed circle shape, which acts as a background. It's strokeEnd value is 1, as it's fixed and a complete circle. The second shape is the progressive circle, which will be animated via strokeEnd to show its progress. We used the getShapeLayerForRect function to create a circle via the CAShapeLayer class in the CoreAnimation framework.
More information about drawing with Bezier Path and Core Animation can be found in Chapter 5, Animations and Graphics.
- Then, we add the updateProgess function that updates the progress by animating the progressive layer strokeEnd property.
- Now, take a look at an outlet of the progressive view in ViewController.swift:
@IBOutlet weak var circularProgressView: CircularProgressBar!
- Then override viewDidAppear method to update the progress value to 75% like this:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.circularProgressView.updateProgess(0.75, animated: true,
duration: 2)
}
- Now, build and run; you should see the progress updates with animation:
推薦閱讀
- Linux內核觀測技術BPF
- 嵌入式系統及其應用(第三版)
- 完美應用RHEL 8
- 計算機應用基礎(Windows 7+Office 2016)
- OpenSolaris設備驅動原理與開發
- Learn CUDA Programming
- iOS 10快速開發:18天零基礎開發一個商業應用
- Office 365 User Guide
- VMware vSphere 5.1 Cookbook
- 計算機應用基礎(Windows 7+Office 2010)
- 樹莓派+傳感器:創建智能交互項目的實用方法、工具及最佳實踐
- 微軟360度
- Xamarin Mobile Application Development for Android
- Administering ArcGIS for Server
- 計算機系統平臺