如何使用Swift在iOS 8上显示带有文本的活动指示器?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用Swift在iOS 8上显示带有文本的活动指示器?相关的知识,希望对你有一定的参考价值。
我想以编程方式显示带有文本的活动指示器,如照片应用程序中的那个(编辑并保存图片后)。我怎样才能做到这一点?
答案
Xcode 8.2.1•Swift 3.0.2
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var filterButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
let destinationUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
.appendingPathComponent("filteredImage.png")
let imagePicker = UIImagePickerController()
let messageFrame = UIView()
var activityIndicator = UIActivityIndicatorView()
var strLabel = UILabel()
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
func activityIndicator(_ title: String) {
strLabel.removeFromSuperview()
activityIndicator.removeFromSuperview()
effectView.removeFromSuperview()
strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
strLabel.text = title
strLabel.font = .systemFont(ofSize: 14, weight: UIFontWeightMedium)
strLabel.textColor = UIColor(white: 0.9, alpha: 0.7)
effectView.frame = CGRect(x: view.frame.midX - strLabel.frame.width/2, y: view.frame.midY - strLabel.frame.height/2 , width: 160, height: 46)
effectView.layer.cornerRadius = 15
effectView.layer.masksToBounds = true
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
activityIndicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
activityIndicator.startAnimating()
effectView.addSubview(activityIndicator)
effectView.addSubview(strLabel)
view.addSubview(effectView)
}
func saveImage() {
do {
try imageView.image?.data?.write(to: destinationUrl, options: .atomic)
print("file saved")
} catch {
print(error)
}
}
func applyFilterToImage() {
imageView.image = imageView.image?.applying(contrast: 1.5)
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/a/a8/VST_images_the_Lagoon_Nebula.jpg"), let data = try? Data(contentsOf: url), let image = UIImage(data: data) else { return }
view.backgroundColor = UIColor(white: 0, alpha: 1)
imageView.image = image
}
@IBAction func startSavingImage(_ sender: AnyObject) {
saveButton.isEnabled = false
filterButton.isEnabled = false
activityIndicator("Saving Image")
DispatchQueue.main.async {
self.saveImage()
DispatchQueue.main.async {
self.effectView.removeFromSuperview()
self.saveButton.isEnabled = true
self.filterButton.isEnabled = true
}
}
}
@IBAction func filterAction(_ sender: AnyObject) {
filterButton.isEnabled = false
saveButton.isEnabled = false
activityIndicator("Applying Filter")
DispatchQueue.main.async {
self.applyFilterToImage()
DispatchQueue.main.async {
self.effectView.removeFromSuperview()
self.filterButton.isEnabled = true
self.saveButton.isEnabled = true
}
}
}
@IBAction func cameraAction(_ sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [AnyHashable: Any]!) {
dismiss(animated: true, completion: nil)
imageView.image = image
}
}
extension Data {
var image: UIImage? { return UIImage(data: self) }
}
extension UIImage {
var data: Data? { return UIImagePNGRepresentation(self) }
func applying(contrast value: NSNumber) -> UIImage? {
guard let ciImage = CIImage(image: self)?.applyingFilter("CIColorControls", withInputParameters: [kCIInputContrastKey: value]) else { return nil }
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
UIImage(ciImage: ciImage).draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
Xcode 9.0•Swift 4.0
func activityIndicator(_ title: String) {
strLabel.removeFromSuperview()
activityIndicator.removeFromSuperview()
effectView.removeFromSuperview()
strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
strLabel.text = title
strLabel.font = .systemFont(ofSize: 14, weight: .medium)
strLabel.textColor = UIColor(white: 0.9, alpha: 0.7)
effectView.frame = CGRect(x: view.frame.midX - strLabel.frame.width/2, y: view.frame.midY - strLabel.frame.height/2 , width: 160, height: 46)
effectView.layer.cornerRadius = 15
effectView.layer.masksToBounds = true
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
activityIndicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
activityIndicator.startAnimating()
effectView.contentView.addSubview(activityIndicator)
effectView.contentView.addSubview(strLabel)
view.addSubview(effectView)
}
另一答案
Xcode 10.1•Swift 4.2
import UIKit
class ProgressHUD: UIVisualEffectView {
var title: String?
var theme: UIBlurEffect.Style = .light
let strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
let activityIndicator = UIActivityIndicatorView()
init(title: String, theme: UIBlurEffect.Style = .light) {
super.init(effect: UIBlurEffect(style: theme))
self.title = title
self.theme = theme
[activityIndicator, strLabel].forEach(contentView.addSubview(_:))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
if let superview = self.superview {
frame = CGRect(x: superview.frame.midX - strLabel.frame.width / 2,
y: superview.frame.midY - strLabel.frame.height / 2, width: 160, height: 46)
layer.cornerRadius = 15.0
layer.masksToBounds = true
activityIndicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
activityIndicator.startAnimating()
strLabel.text = title
strLabel.font = .systemFont(ofSize: 14, weight: UIFont.Weight.medium)
switch theme {
case .dark:
strLabel.textColor = .white
activityIndicator.style = .white
default:
strLabel.textColor = .gray
activityIndicator.style = .gray
}
}
}
func show() {
self.isHidden = false
}
func hide() {
self.isHidden = true
}
}
使用:
let progress = ProgressHUD(title: "Authorization", theme: .dark)
[progress].forEach(view.addSubview(_:))
另一答案
With auto width and theme support also detects rotate while busy (Swift 3 version)
使用方式如下:
var progressView: ProgressView?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.progressView = ProgressView(message: "Work in progress!",
theme: .dark,
以上是关于如何使用Swift在iOS 8上显示带有文本的活动指示器?的主要内容,如果未能解决你的问题,请参考以下文章
iOS 8 上的 UIActivityViewController 显示带有自定义活动的“更多”按钮
Swift 3 iOS 10 - 带有图像和文本的 UICollectionView 无法正确显示
在 UILabel 中显示 HTML 文本,性能问题。 [iPhone SDK、iOS 8、Swift]