我有一个UIProgressView
,我给它一个progressImage
,随着进度条的进展,我想展示它。我该怎么做?
目前发生的情况是,整个图像总是适合在进度栏内,它只是被压缩。相反,我只想显示图像的一部分(例如左边)。
发布于 2022-07-31 14:14:56
您需要创建自己的“自定义进度视图”。
一种方法是在图像视图上使用CALayer
作为掩码,将层的大小调整为自定义视图宽度的百分比。
下面是一个简单的例子..。
自定义进度视图
class MyProgressView: UIView {
// image that will be "revealed"
public var image: UIImage? {
didSet {
bkgView.image = image
}
}
public var progress: Float {
set {
// keep the value between 0.0 and 1.0
_progress = max(min(newValue, 1.0), 0.0)
setNeedsLayout()
}
get {
return _progress
}
}
private var _progress: Float = 0.0
private let bkgView = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
bkgView.translatesAutoresizingMaskIntoConstraints = false
addSubview(bkgView)
let g = self
NSLayoutConstraint.activate([
bkgView.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
bkgView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
bkgView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
bkgView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
])
}
override func layoutSubviews() {
super.layoutSubviews()
// width to "reveal" will be the percentage of self's width
let w: CGFloat = bounds.width * CGFloat(_progress)
var r = bounds
r.size.width = w
// create a mask layer
let msk = CALayer()
// can be any color other than clear
msk.backgroundColor = UIColor.black.cgColor
msk.frame = r
bkgView.layer.mask = msk
}
}
样例视图控制器
class MyProgessVC: UIViewController {
let myProgressView = MyProgressView()
let standardProgressView = UIProgressView()
let infoLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
let g = view.safeAreaLayoutGuide
// make sure we can load the image we want to use for our custom progress view
guard let img = UIImage(named: "pvBKG") else { return }
// add the standard progress view
standardProgressView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(standardProgressView)
// add our custom progress view
myProgressView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myProgressView)
// add a slider to set the progress view percentage
let slider = UISlider()
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
slider.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(slider)
// add a label to show the current progress
infoLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(infoLabel)
infoLabel.textAlignment = .center
NSLayoutConstraint.activate([
// let's put the standard progress view near the top
standardProgressView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
// with 20-points on each side
standardProgressView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
standardProgressView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
// put our custom "progress view" below the standard one
myProgressView.topAnchor.constraint(equalTo: standardProgressView.bottomAnchor, constant: 40.0),
// with 20-points on each side
myProgressView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
myProgressView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
// we'll make the height equal to the image height
myProgressView.heightAnchor.constraint(equalToConstant: img.size.height),
// put the slider below the progress views
slider.topAnchor.constraint(equalTo: myProgressView.bottomAnchor, constant: 40.0),
slider.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
slider.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
// put the info label below the slider
infoLabel.topAnchor.constraint(equalTo: slider.bottomAnchor, constant: 40.0),
infoLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
infoLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
])
// color for progress view "right-side"
myProgressView.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
// set the "reveal" image
myProgressView.image = img
updateInfoLabel()
}
@objc func sliderChanged(_ sender: UISlider) {
// set .progress on each to the slider value
myProgressView.progress = sender.value
standardProgressView.progress = sender.value
updateInfoLabel()
}
func updateInfoLabel() {
infoLabel.text = "\(myProgressView.progress)"
}
}
我们添加了一个“标准”UIProgressView
,一个自定义MyProgressView
的实例,一个交互设置进度值的UISlider
,以及一个显示该值的标签。
将此图像用于进度视图“显示”图像:
运行时如下所示:
如果您想要模拟默认UIProgressView
的动画功能(如调用.setProgress(0.75, animated: true)
),那么还需要做一些工作:)
https://stackoverflow.com/questions/73171331
复制相似问题