Как программно добавить простую панель загрузки (выполнения) по умолчанию в приложении iphone - PullRequest
37 голосов
/ 02 апреля 2012

Я использую http-связь в приложении «Мой iPhone».Я хочу показать индикатор выполнения во время загрузки данных с сервера.Как я могу сделать это программно?

Я просто хочу индикатор выполнения по умолчанию.Ничего особенного, как в Android мы делаем ProgressDialog.show();, есть ли один вкладыш для отображения индикатора прогресса в iphone?

Ответы [ 16 ]

1 голос
/ 26 августа 2017

Swift 3 версия решения @ enrique7mc

    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()
1 голос
/ 14 ноября 2016

Я хотел опубликовать созданное мной решение, в котором будет отображаться индикатор выполнения в отдельном окне, показывающий прогресс с результатами, которые могут быть перечислены.

Прикрепленное изображение ниже того, как оно выглядит.

enter image description here

Совместимость: Swift 3

Особенности: Код с резьбойToRun & Cancel + Кнопка Готово.Автоматически показывает оставшуюся сумму прогресса, если вы хотите использовать функцию updateProgress.

Код очень прост и легко модифицируется, это просто раскадровка и контроллер представления.

  1. Используйте приведенный ниже XML-код и сохраните его под финальным именем, которое я предлагаю ниже, где-нибудь в вашем проекте.

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>
Сохраните следующий код ниже в свой проект с именем 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, и предоставьте необходимую информацию для связи с поповером.

enter image description here

Ниже приведен пример кода ниже, если вам нужноэто:

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 (), будет работать как фоновый поток.Для доступа к любому пользовательскому интерфейсу codeToRun имеет доступ к progressWindowViewController, который был предварительно настроен для подключения к пользовательскому интерфейсу с этими элементами под вашим контролем.

@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!

Я использую это во всех своих проектах в любое время, когда явыполнение синхронизации, загрузки или трудоемкого сетевого задания.

Здесь также отображается индикатор активности, показывающий, что вы пытаетесь что-то сделать.Все это можно настроить, так как его очень легко просмотреть и понять, как оно работает.Надеюсь, это поможет вам сэкономить некоторое время и быстро получить окно типа прогресса.

0 голосов
/ 17 мая 2019

Swift 5.x версия кода Swift @ enrique7mc:

var indicator: UIActivityIndicatorView = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.gray)
indicator.frame = CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0)
indicator.center = view.center
view.addSubview(indicator)
indicator.bringSubviewToFront(view)
UIApplication.shared.isNetworkActivityIndicatorVisible = true

Начните с

indicator.startAnimating()

Остановите это с

indicator.stopAnimating()

Это добавляет небольшой ActivityIndicator (поворотный круг, документация Apple ) к середине экрана и строке состояния. Первый из них будет очищен, как только вы переключитесь на другой ViewController, а тот, что в строке состояния, не будет - вам придется отключить его вручную.

0 голосов
/ 28 июля 2016

App Delegate.h

-(void)showLoader;

-(void)hideLoder;

Приложение 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.и вы можете вызвать загрузчик вот так.

[app showLoader];

и

[app hideLoder];

0 голосов
/ 21 июля 2016

Добавить свойство

@ свойство (сильное, неатомное) IBOutlet UIActivityIndicatorView * индикатор;

Для начала анимации

[self.indicator startAnimating];

Чтобы остановить анимацию

[self.indicator stopAnimating];

0 голосов
/ 26 января 2016

Я также добавлю здесь свои два цента:

Я создал этот ARSLineProgress preloader, который вы также можете проверить здесь на Appetize .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...