我有一个像Snapchat和Instagram故事一样的进度视图。进度视图到达结束或点击按钮后,我的内容会发生变化。
我正在重置内容更改时的进度视图。一切都按预期工作,而没有干预。但是当点击下一个按钮时,进度视图不会再次开始,直到另一个循环执行。
您可以快速查看video here。
我在研究期间偶然发现this question,我有相同的情况,但我无法将该原则应用于swift 3的新手。
这是我的代码,任何帮助都将受到高度赞赏:
func startTimer(){
self.timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(myVievController.nextItem), userInfo: nil, repeats: false)
}
func updateProgressBar() {
self.progressView.setProgress(1.0, animated: false)
UIView.animate(withDuration: 2.8, animations: {() -> Void in
self.progressView.layoutIfNeeded()
}, completion: { finished in
if finished {
self.progressView.setProgress(0, animated: false)
}
})
}
func nextItem(){
// ...
self.updateUI(item: self.myCurrentItem)
// ...
}
func updateUI(item:MyItem){
self.updateProgressBar()
self.timer.invalidate()
self.startTimer()
// Clear old item and fill new values etc...
}
@IBAction func nextButtonPressed(_ sender: UIButton) {
self.nextItem()
}
答案 0 :(得分:0)
您可能需要这样的内容来更新进度条:self.progressView.setProgress(0, animated: false)
func updateProgressBar() {
DispatchQueue.main.async {
self.progressView.setProgress(0.1, animated: false)
}
if self.progressView.Progress == 1.0 {
self.timer.invalidate()
} else {
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(myVievController.updateProgressBar), userInfo: nil, repeats: false)
}
}
然后您可以使计时器无效并在100%
时停止更新答案 1 :(得分:0)
也可以使用子类:
function renderLabel() {
var label = this.renderer.label("How do I move this center and under the legend.")
.css({
width: '180px'
})
.attr({
'stroke': 'silver',
'stroke-width': 1,
'r': 5,
'padding': 10
})
.add();
label.align(Highcharts.extend(label.getBBox(), {
align: 'center',
x: 0, // offset
verticalAlign: 'bottom',
y: 60 // offset
}), null, 'spacingBox');
}
当您需要从头开始再次启动progressView时,可以通过调用class HelloWorld: UIProgressView {
func startProgressing(duration: TimeInterval, resetProgress: Bool, completion: @escaping (Void) -> Void) {
stopProgressing()
// Reset to 0
progress = 0.0
layoutIfNeeded()
// Set the 'destination' progress
progress = 1.0
// Animate the progress
UIView.animate(withDuration: duration, animations: {
self.layoutIfNeeded()
}) { finished in
// Remove this guard-block, if you want the completion to be called all the time - even when the progression was interrupted
guard finished else { return }
if resetProgress { self.progress = 0.0 }
completion()
}
}
func stopProgressing() {
// Because the 'track' layer has animations on it, we'll try to remove them
layer.sublayers?.forEach { $0.removeAllAnimations() }
}
}
来使用它。当完成动画时,会调用完成,因此您可以更改视图等。
使用示例:
-startProgressing()
答案 2 :(得分:0)
示例
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var progressView: UIProgressView!
var timer : Timer?
var timerCount = 0
var imageArray : Array<UIImage> = []
// MARK: - Lifecycle -
override func viewDidLoad() {
super.viewDidLoad()
// create gradient images
buildImageArray(duration: 3, highlightPercentage: 10.0, mainColor: .green, highlightColor: .yellow, imageWidth: Double(progressView.frame.width))
// set progressView to first image
progressView.progressImage = imageArray[0]
// set progressView progress
progressView.progress = 0.7
// schedule timer
if self.timer == nil {
self.timer = Timer.scheduledTimer(timeInterval: 1/60, target: self, selector: #selector(updateGradient), userInfo: nil, repeats: true)
RunLoop.main.add(self.timer!, forMode: .common)
}
}
func buildImageArray(duration: Int, highlightPercentage: Double, mainColor: UIColor, highlightColor: UIColor, imageWidth: Double){
let keyFrames = duration * 60
for i in 0..<keyFrames {
// Drawing code
let frame = CGRect(x: 0.0, y: 0.0, width: imageWidth, height: 1.0)
let layer = CAGradientLayer()
layer.frame = frame
layer.startPoint = CGPoint(x: 0.0, y: 0.5)
layer.endPoint = CGPoint(x: 1.0, y: 0.5)
var colors : [UIColor] = []
for n in 0..<keyFrames {
colors.append(mainColor)
}
let highlightKeyFrames : Int = Int(floor(Double(keyFrames) * (highlightPercentage/100)))
// 300 * .3 = 90 kf
for x in 0..<highlightKeyFrames {
let p = i+x
if p < keyFrames {
colors[p] = highlightColor
}
}
layer.colors = colors.map { $0.cgColor }
layer.bounds = frame
let image = UIImage.imageWithLayer(layer: layer)
imageArray.append(image)
}
}
// updateGradient
@objc func updateGradient(){
// crop image to match progress
let newWidth = self.progressView.frame.width * CGFloat(progressView.progress)
let progressImage = imageArray[timerCount].crop(rect: CGRect(x: 0, y: 0, width: newWidth, height: 1))
progressView.progressImage = progressImage
// increment timer
timerCount = timerCount + 1
if timerCount >= imageArray.count {
timerCount = 0
}
}
}
extension UIImage {
class func imageWithLayer(layer: CALayer) -> UIImage {
UIGraphicsBeginImageContextWithOptions(layer.bounds.size, layer.isOpaque, 0.0)
layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}
func crop( rect: CGRect) -> UIImage {
var rect = rect
rect.origin.x*=self.scale
rect.origin.y*=self.scale
rect.size.width*=self.scale
rect.size.height*=self.scale
let imageRef = self.cgImage!.cropping(to: rect)
let image = UIImage(cgImage: imageRef!, scale: self.scale, orientation: self.imageOrientation)
return image
}
}