如何以编程方式在iPhone应用程序中添加一个简单的默认加载(进度)栏

我在我的iPhone应用程序中使用http通信。 我想在从服务器加载数据时显示进度条。 我怎样才能以编程方式?

我只想要一个默认的进度条。 没有什么奇特的,就像在android中我们做ProgressDialog.show(); ,是否有任何一个class轮在iPhone显示进度条?

 UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; indicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0); indicator.center = self.view.center; [self.view addSubview:indicator]; [indicator bringSubviewToFront:self.view]; [UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE; 

当你想显示指标时写下面的代码

 [indicator startAnimating]; 

当你想隐藏指标时写下面的代码

 [indicator stopAnimating]; 

将@ Hiren的答案翻译成Swift

 var indicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) indicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0); indicator.center = view.center view.addSubview(indicator) indicator.bringSubviewToFront(view) UIApplication.sharedApplication().networkActivityIndicatorVisible = true 

显示指示器

 indicator.startAnimating() 

停止指示器

 indicator.stopAnimating() 

我build议使用NSURLConnection 。 你需要的方法是:

 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [self.resourceData setLength:0]; self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]]; } -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.resourceData appendData:data]; NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]]; self.progressBar.progress = [resourceLength floatValue] / [self.filesize floatValue]; } -(void)connectionDidFinishLoading:(NSURLConnection *)connection { self.progressBar.hidden = YES; } 

和头文件:

 @property (nonatomic, retain) UIProgressView *progressBar; @property (nonatomic, retain) NSMutableData *resourceData; @property (nonatomic, retain) NSNumber *filesize; 

希望能帮助到你

UIProgressView是您正在寻找的类: Apple Docs

您需要使用setProgress:animated:方法更新显示的进度。 最有可能的地方是从networking处理接收到的数据。

您可以使用IOS内置的UIProgressView。 以下是代码片段:

 UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; [self.view addSubview:progressView]; [progressView setProgress:50.0]; 

您可以使用setFrame:在视图上定位进度条。

尝试下面的代码

 float progress; //components UIProgressView *progressBar; progressBar=[[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault]; [progressBar setFrame:CGRectMake(30.0, 75.0, 200.0, 80.0)]; int prog=progress*100; progressStr=[NSString stringWithFormat:@"%d%%",prog]; [progressBar setProgress:progress]; 

为了保持这个问题完全更新,我已经翻译了@inrique7mc的答案Swift3.0之后,他从@ Hiren的答案的翻译。

 var indicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) indicator.frame = CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0) indicator.center = view.center view.addSubview(indicator) indicator.bringSubview(toFront: view) UIApplication.shared.isNetworkActivityIndicatorVisible = true 

启动和停止进度栏的方式与@ enrique7mc指出的相同。

 indicator.startAnimating() indicator.stopAnimating() 

我知道这是一个老问题,但我已经写了一个全局静态方法来做这种types的事情从任何视图,基于上述答案。

主要更新是:

  • 支持活动指示符后面的可选不透明覆盖
  • 使用活动指标的默认框架大小
  • 使用.WhiteLarge指示器样式

在我的AppHelper.swift中:

 static func showActivityIndicator(view: UIView, withOpaqueOverlay: Bool) { // this will be the alignment view for the activity indicator var superView: UIView = view // if we want an opaque overlay, do that work first then put the activity indicator within that view; else just use the passed UIView to center it if withOpaqueOverlay { let overlay = UIView() overlay.frame = CGRectMake(0.0, 0.0, view.frame.width, view.frame.height) overlay.layer.backgroundColor = UIColor.blackColor().CGColor overlay.alpha = 0.7 overlay.tag = activityIndicatorOverlayViewTag overlay.center = superView.center overlay.hidden = false superView.addSubview(overlay) superView.bringSubviewToFront(overlay) // now we'll work on adding the indicator to the overlay (now superView) superView = overlay } let indicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge) indicator.center = superView.center indicator.tag = activityIndicatorViewTag indicator.hidden = false superView.addSubview(indicator) superView.bringSubviewToFront(indicator) indicator.startAnimating() // also indicate network activity in the status bar UIApplication.sharedApplication().networkActivityIndicatorVisible = true } static func hideActivityIndicator(view: UIView) { // stop the network activity animation in the status bar UIApplication.sharedApplication().networkActivityIndicatorVisible = false // remove the activity indicator and optional overlay views view.viewWithTag(activityIndicatorViewTag)?.removeFromSuperview() view.viewWithTag(activityIndicatorOverlayViewTag)?.removeFromSuperview() } 

尝试MBProgressHUD 。

这很简单,有几个进度animation选项,并能够添加一些自定义。 它显示全屏。 它应该适用于任何最新的iOS版本。

或者尝试LDProgressView如果你想要更多的东西:)它看起来像OSX的进度条。

我想发布一个我创build的解决scheme,它将在单独的窗口中显示一个进度条,以显示可能被列出的结果的进度。

附件是下面的图片。

在这里输入图像说明

兼容性:Swift 3

特点:螺纹codeToRun&取消+完成button。 如果您想使用updateProgress函数,则自动显示剩余的进度。

代码非常简单,易于修改,只是一个故事板和一个视图控制器。

  1. 使用下面的XML,并保存在我的项目下面的build议的最终名称。

ProgressWindow.storyboard

 <?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> <device id="retina4_7" orientation="portrait"> <adaptation id="fullscreen"/> </device> <dependencies> <deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/> <capability name="Constraints to layout margins" minToolsVersion="6.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> <!--Progress--> <scene sceneID="5gE-ws-FsC"> <objects> <viewController storyboardIdentifier="progressWindow" title="Progress" id="IB9-Dc-dCV" customClass="ProgressWindowViewController" customModule="WorkOrders" customModuleProvider="target" sceneMemberID="viewController"> <layoutGuides> <viewControllerLayoutGuide type="top" id="Lvc-9P-nmJ"/> <viewControllerLayoutGuide type="bottom" id="xJS-yG-jWM"/> </layoutGuides> <view key="view" contentMode="scaleToFill" id="iDk-68-mde"> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Please Wait..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9ui-W7-ucD"> <rect key="frame" x="16" y="84" width="343" height="21"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ov7-yH-A5z"> <rect key="frame" x="16" y="113" width="343" height="2"/> </progressView> <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" text="Starting Up..." textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bwA-YT-FcE"> <rect key="frame" x="16" y="123" width="343" height="464"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> </textView> <navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RPs-Mo-Cfx"> <rect key="frame" x="-4" y="20" width="383" height="44"/> <items> <navigationItem title="Starting Sync..." id="Y87-LY-5o5"> <barButtonItem key="rightBarButtonItem" title="Cancel" id="AD3-in-E6j"> <connections> <action selector="cancelNavItemButtonActionWithSender:" destination="IB9-Dc-dCV" id="IF1-MG-v2x"/> </connections> </barButtonItem> </navigationItem> </items> </navigationBar> <button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6lh-KK-lX1"> <rect key="frame" x="113" y="595" width="150" height="42"/> <fontDescription key="fontDescription" type="system" pointSize="25"/> <state key="normal" title="Done"/> <state key="disabled" title="Please Wait..."/> <connections> <action selector="doneButtonActionWithSender:" destination="IB9-Dc-dCV" eventType="touchUpInside" id="KQH-Th-NAC"/> </connections> </button> </subviews> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstAttribute="leadingMargin" secondItem="ov7-yH-A5z" secondAttribute="leading" id="9Gm-bd-GY6"/> <constraint firstItem="xJS-yG-jWM" firstAttribute="top" secondItem="bwA-YT-FcE" secondAttribute="bottom" constant="20" id="CT1-0k-Skt"/> <constraint firstItem="6lh-KK-lX1" firstAttribute="top" secondItem="bwA-YT-FcE" secondAttribute="bottom" constant="8" symbolic="YES" id="Fb8-eP-lxu"/> <constraint firstItem="RPs-Mo-Cfx" firstAttribute="leading" secondItem="iDk-68-mde" secondAttribute="leadingMargin" constant="-20" id="JSY-Na-oAF"/> <constraint firstItem="xJS-yG-jWM" firstAttribute="top" secondItem="6lh-KK-lX1" secondAttribute="bottom" constant="30" id="NHY-fO-W26"/> <constraint firstAttribute="trailingMargin" secondItem="RPs-Mo-Cfx" secondAttribute="trailing" constant="-20" id="QxH-pj-oOA"/> <constraint firstItem="RPs-Mo-Cfx" firstAttribute="top" secondItem="Lvc-9P-nmJ" secondAttribute="bottom" id="VIf-63-vaw"/> <constraint firstAttribute="trailingMargin" secondItem="bwA-YT-FcE" secondAttribute="trailing" id="WxH-hu-ZVQ"/> <constraint firstAttribute="leadingMargin" secondItem="bwA-YT-FcE" secondAttribute="leading" id="XEd-Ba-ZfL"/> <constraint firstItem="bwA-YT-FcE" firstAttribute="top" secondItem="ov7-yH-A5z" secondAttribute="bottom" constant="8" id="Xjr-bH-ILB"/> <constraint firstItem="6lh-KK-lX1" firstAttribute="centerY" secondItem="iDk-68-mde" secondAttribute="centerY" id="ZU1-pD-czP"/> <constraint firstItem="ov7-yH-A5z" firstAttribute="top" secondItem="9ui-W7-ucD" secondAttribute="bottom" constant="8" symbolic="YES" id="avI-Ab-G29"/> <constraint firstAttribute="leadingMargin" secondItem="9ui-W7-ucD" secondAttribute="leading" id="dse-zV-g00"/> <constraint firstItem="6lh-KK-lX1" firstAttribute="centerX" secondItem="iDk-68-mde" secondAttribute="centerX" id="i5Q-oY-DdV"/> <constraint firstAttribute="trailingMargin" secondItem="9ui-W7-ucD" secondAttribute="trailing" id="jqu-1f-IuA"/> <constraint firstItem="9ui-W7-ucD" firstAttribute="top" secondItem="RPs-Mo-Cfx" secondAttribute="bottom" constant="20" id="nrH-ey-Zcm"/> <constraint firstAttribute="trailingMargin" secondItem="ov7-yH-A5z" secondAttribute="trailing" id="qha-Es-6Au"/> </constraints> <variation key="default"> <mask key="constraints"> <exclude reference="ZU1-pD-czP"/> <exclude reference="CT1-0k-Skt"/> </mask> </variation> </view> <connections> <outlet property="cancelNavButton" destination="AD3-in-E6j" id="SJc-Bc-N6j"/> <outlet property="currentProgressLabel" destination="9ui-W7-ucD" id="zij-yQ-MFX"/> <outlet property="doneButton" destination="6lh-KK-lX1" id="rh2-RF-4ak"/> <outlet property="navItemLabel" destination="Y87-LY-5o5" id="ijO-a7-TrD"/> <outlet property="navigationBar" destination="RPs-Mo-Cfx" id="WEq-F4-Pup"/> <outlet property="theProgressBar" destination="ov7-yH-A5z" id="FUE-9J-iBh"/> <outlet property="theTextView" destination="bwA-YT-FcE" id="1sR-23-NZH"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="TH6-NB-Eos" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> <point key="canvasLocation" x="-492" y="1474"/> </scene> </scenes> </document> 
  1. 将下面的代码保存到名为ProgressWindowViewController.swift的项目中

ProgressWindowViewController.swift

 import UIKit protocol progressWindowDelegate : class{ var titleToGive : String {get} func codeToRun(progressWindowViewController:ProgressWindowViewController) var codeToCancel : ()->() {get} } class ProgressWindowViewController: UIViewController { @IBOutlet weak var theTextView: UITextView! @IBOutlet weak var currentProgressLabel: UILabel! @IBOutlet weak var theProgressBar: UIProgressView! @IBOutlet weak var navItemLabel: UINavigationItem! @IBOutlet weak var doneButton: UIButton! @IBOutlet weak var cancelNavButton: UIBarButtonItem! @IBOutlet weak var navigationBar: UINavigationBar! //For showing network activity var indicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) //Sets delegate weak var controllerDelegate:progressWindowDelegate? = nil override func viewDidLoad() { super.viewDidLoad() navItemLabel.title = controllerDelegate!.titleToGive //Run on the main thread first then in background thread. DispatchQueue.main.async { DispatchQueue.global(qos: .background).async{ self.controllerDelegate?.codeToRun(progressWindowViewController: self) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func writeToProgressWindow(text:NSMutableAttributedString){ DispatchQueue.main.async(execute: { print("dispatch_queue_get_main_queue -> writeToProgressWindow()") self.theTextView.attributedText = text }) } func updateNetworkIndicator(active:Bool){ DispatchQueue.main.async(execute: { if(active){ UIApplication.shared.isNetworkActivityIndicatorVisible = true }else{ UIApplication.shared.isNetworkActivityIndicatorVisible = false } }) } func updateProgress(updatetext:String,amount:Int,left:Int){ DispatchQueue.main.async(execute: { print("dispatch_queue_get_main_queue -> updatingProgress()") self.currentProgressLabel.text = updatetext+" : \(amount) / \(left)" self.theProgressBar.setProgress(Float(amount/left), animated: true) //progress is represented as a percentage of the total }) } func updateProgressWindowWeFinished(title:String){ //Enable done button and Disable/Hide Cancel Button. Add Final Messages DispatchQueue.main.async(execute: { self.doneButton.isEnabled = true self.navItemLabel.title = title self.cancelNavButton.isEnabled = false self.cancelNavButton.tintColor = UIColor.clear }) } @IBAction func cancelNavItemButtonAction(sender: UIBarButtonItem) { //Run on the main thread first then in background thread. DispatchQueue.main.async { DispatchQueue.global(qos: .background).sync{ print("dispatch_queue_priority_default") self.controllerDelegate?.codeToCancel() } self.dismiss(animated: true, completion: nil)//closes the window. } } @IBAction func doneButtonAction(sender: UIButton) { self.dismiss(animated: true, completion: nil)//closes the window. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ } 

3.)使用你只需将调用它的视图控制器设置为progressWindowDelegate并提供所需的信息与popover进行通信。

在这里输入图像说明

下面是一些示例代码,如果你需要它:

SampleViewControllerWithYesButton.swift

 class SyncViewController: UIViewController, progressWindowDelegate { var codeToCancel = {print("code to cancel")} var titleToGive = "Starting Sync..." func codeToRun(progressWindowViewController:ProgressWindowViewController) { print("code to run") } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func yesButtonAction(_ sender: UIButton) { let storyboard = UIStoryboard(name: "ProgressWindow", bundle: nil) let controller = storyboard.instantiateViewController(withIdentifier: "progressWindow") as! ProgressWindowViewController controller.controllerDelegate = self self.present(controller, animated: true, completion: nil) } @IBAction func noButtonAction(_ sender: UIButton) { tabBarController?.selectedIndex = 1 //Send them to the list then. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ } 

无论你在codeToRun()中放置什么,都将作为后台线程运行。 要访问任何UI,codeToRun可以访问progressWindowViewController,它已经被预先configuration好,以便用这些元素连接到你的UI。

 @IBOutlet weak var theTextView: UITextView! @IBOutlet weak var currentProgressLabel: UILabel! @IBOutlet weak var theProgressBar: UIProgressView! @IBOutlet weak var navItemLabel: UINavigationItem! @IBOutlet weak var doneButton: UIButton! @IBOutlet weak var cancelNavButton: UIBarButtonItem! @IBOutlet weak var navigationBar: UINavigationBar! 

任何时候我在做同步,上传或耗时的networking任务时,我都会在所有项目中使用它。

这也显示活动的指示器,以及显示你正在尝试做某事。 所有这些都可以定制,因为它很容易查看并了解它是如何工作的。 希望这可以帮助您节省一些时间,快速获得进度types的窗口。

Swift 3版本的enrique7mc解决scheme

  var indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) indicator.frame = CGRect(x: 0, y: 0, width: 40, height: 40) indicator.center = view.center view.addSubview(indicator) indicator.bringSubview(toFront: view) UIApplication.shared.isNetworkActivityIndicatorVisible = true indicator.startAnimating() indicator.stopAnimating() 

我也会在这里投入我的两分钱:

我已经创build了这个ARSLineProgress preloader,你也可以在这里testingAppetize 。

添加属性

@属性(强,非primefaces)IBOutlet UIActivityIndi​​catorView *指标;

开始animation

[self.indicator startAnimating];

停止animation

[self.indicator stopAnimating];

App Delegate.h

 -(void)showLoader; -(void)hideLoder; 

App Delegate.m

 @implementation AppDelegate AppDelegate *app; -(void)showLoader { if(loaderView== NULL) { loaderView=[[UIView alloc] initWithFrame:self.window.frame]; [loaderView setBackgroundColor:[UIColor blackColor]]; [loaderView setAlpha:0.5]; spinner = [[UIActivityIndicatorView alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; [loaderView addSubview:spinner]; spinner.center = CGPointMake(loaderView.frame.size.width/2-10, loaderView.frame.size.height/2-10); spinner.hidesWhenStopped = YES; } [spinner startAnimating]; [self.window addSubview:loaderView]; [self.window bringSubviewToFront:spinner]; [self.window bringSubviewToFront:loaderView]; } -(void)hideLoder { if (spinner!= NULL) { [spinner stopAnimating]; } [loaderView removeFromSuperview]; } 

现在导入“AppDelegate.h”类,你可以调用loader.and你可以像这样调用loader。

[app showLoader];

[app hideLoder];