totales rotacion razones razon proveedores promedio por pagar hallar financieras fijos ejercicios ejercicio ejemplo cuentas como cobrar activos ios swift uiview uiactivityindicatorview uialertcontroller

ios - razones - rotacion de activos totales



¿Cómo mostrar el indicador de actividad en el centro de UIAlertController? (12)

tl; dr

Todas las demás respuestas están desactivadas :) Ver documentación:

Importante

La clase UIAlertController está diseñada para usarse tal como está y no admite subclases. La jerarquía de vistas para esta clase es privada y no debe modificarse .

Problema

El problema no es el UIAlertController. Esta es una IU muy simple, una vista de pila o dos, dependiendo de si desea que el UIActivityIndicatorView quede en la etiqueta del título o debajo del título. La animación de presentación es lo que queremos.

El código a continuación se basa en la sesión de WWDC A Look Inside Presentation Controllers .

Recrear el controlador de presentación:

@interface LOActivityAlertControllerPresentationController : UIPresentationController @end @interface LOActivityAlertControllerPresentationController () @property (nonatomic) UIView *dimmerView; @end @implementation LOActivityAlertControllerPresentationController - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController { self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController]; if (self) { _dimmerView = [[UIView alloc] init]; _dimmerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; _dimmerView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4]; UIView *presentedView = [self presentedView]; presentedView.layer.cornerRadius = 8.0; UIInterpolatingMotionEffect *centerXMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; centerXMotionEffect.minimumRelativeValue = @(-10.0); centerXMotionEffect.maximumRelativeValue = @(10.0); UIInterpolatingMotionEffect *centerYMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; centerYMotionEffect.minimumRelativeValue = @(-10.0); centerYMotionEffect.maximumRelativeValue = @(10.0); UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init]; group.motionEffects = [NSArray arrayWithObjects:centerXMotionEffect, centerYMotionEffect, nil]; [presentedView addMotionEffect:group]; } return self; } - (CGRect)frameOfPresentedViewInContainerView { UIView *containerView = [self containerView]; UIView *presentedView = [self presentedView]; CGSize size = [presentedView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; CGRect frame = CGRectZero; frame.origin = CGPointMake(CGRectGetMidX([containerView frame]) - (size.width / 2.0), CGRectGetMidY([containerView frame]) - (size.height / 2.0)); frame.size = size; return frame; } - (void)presentationTransitionWillBegin { UIViewController *presentingViewController = [self presentingViewController]; UIView *containerView = [self containerView]; UIView *presentedView = [self presentedView]; UIView *dimmerView = [self dimmerView]; dimmerView.alpha = 0.0; dimmerView.frame = [containerView bounds]; [containerView insertSubview:dimmerView atIndex:0]; presentedView.center = [containerView center]; [[presentingViewController transitionCoordinator] animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { dimmerView.alpha = 1.0; } completion:NULL]; } - (void)containerViewWillLayoutSubviews { [super containerViewWillLayoutSubviews]; UIView *containerView = [self containerView]; UIView *presentedView = [self presentedView]; UIView *dimmerView = [self dimmerView]; dimmerView.frame = [containerView bounds]; presentedView.frame = [self frameOfPresentedViewInContainerView]; } - (void)dismissalTransitionWillBegin { UIViewController *presentingViewController = [self presentingViewController]; UIView *dimmerView = [self dimmerView]; [[presentingViewController transitionCoordinator] animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { dimmerView.alpha = 0.0; } completion:NULL]; } @end

Transición animada:

@interface LOActivityAlertControllerAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning> @property (getter=isPresentation) BOOL presentation; @end @implementation LOActivityAlertControllerAnimatedTransitioning - (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext { UIView *containerView = [transitionContext containerView]; UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey]; if (_presentation) { [containerView addSubview:toView]; toView.transform = CGAffineTransformMakeScale(1.6, 1.6); toView.alpha = 0.0; [UIView animateWithDuration:0.2 animations:^{ toView.alpha = 1.0; toView.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } else { [UIView animateWithDuration:0.2 animations:^{ fromView.alpha = 0.0; } completion:^(BOOL finished) { [fromView removeFromSuperview]; [transitionContext completeTransition:YES]; }]; } } - (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext { return 0.2; } @end

Muestra la subclase UIViewController , UIViewController al gusto con XIB:

@interface LOActivityAlertController : UIViewController <UIViewControllerTransitioningDelegate> @property (nonatomic, strong) IBOutlet UIActivityIndicatorView *activityIndicatorView; @property (nonatomic, strong) IBOutlet UILabel *titleLabel; @end @implementation LOActivityAlertController @dynamic title; + (instancetype)alertControllerWithTitle:(NSString *)title { LOActivityAlertController *alert = [LOActivityAlertController new]; alert.title = title; return alert; } - (instancetype)init { self = [super init]; if (self) { self.transitioningDelegate = self; self.modalPresentationStyle = UIModalPresentationCustom; } return self; } - (void)viewDidLoad { [super viewDidLoad]; self.titleLabel.text = self.title; } #pragma mark Properties - (void)setTitle:(NSString *)title { [super setTitle:title]; self.titleLabel.text = title; } #pragma mark UIViewControllerTransitioningDelegate - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source { LOActivityAlertControllerPresentationController *myPresentation = nil; myPresentation = [[LOActivityAlertControllerPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting]; return myPresentation; } - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source; { LOActivityAlertControllerAnimatedTransitioning *transitioning = [LOActivityAlertControllerAnimatedTransitioning new]; transitioning.presentation = YES; return transitioning; } - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { LOActivityAlertControllerAnimatedTransitioning *transitioning = [LOActivityAlertControllerAnimatedTransitioning new]; return transitioning; } @end

Grabación de pantalla

Reportero de errores

rdar: // 37433306 : Haga que el controlador de presentación UIAlertController y el delegado de transición sean API públicas para habilitar la reutilización.

Actualmente tengo un UIAlertController se muestra en la pantalla. La vista de la alerta solo debe mostrar 2 elementos, un título y un UIActivityIndicatorView en el centro de la alerta. A continuación se muestra la función que muestra la alerta y sus elementos.

func displaySignUpPendingAlert() -> UIAlertController { //Create the UIAlertController let pending = UIAlertController(title: "Creating New User", message: nil, preferredStyle: .Alert) //Create the activity indicator to display in it. let indicator = UIActivityIndicatorView(frame: CGRectMake(pending.view.frame.width / 2.0, pending.view.frame.height / 2.0, 20.0, 20.0)) indicator.center = CGPointMake(pending.view.frame.width / 2.0, pending.view.frame.height / 2.0) //Add the activity indicator to the alert''s view pending.view.addSubview(indicator) //Start animating indicator.startAnimating() self.presentViewController(pending, animated: true, completion: nil) return pending }

Sin embargo, el indicador de actividad no se muestra en el centro de la vista, de hecho, se muestra en la parte inferior derecha de la pantalla, lejos de la vista. ¿Cuál es la razón para esto?

EDITAR: Entiendo que puedo codificar los números para la posición del indicador, pero quiero que la alerta funcione en múltiples dispositivos con múltiples tamaños de pantalla y orientaciones.


¿Qué hay de esta manera para Swift 3 y superior:

func showActivityIndiactorViewController(title: String) -> UIAlertController { let pending = UIAlertController(title: "", message: nil, preferredStyle: .alert) let heightConstraint:NSLayoutConstraint = NSLayoutConstraint(item: pending.view, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: self.view.frame.height * 0.10) pending.view.addConstraint(heightConstraint) let label = UILabel() label.text = title label.textColor = UIColor.black label.sizeToFit() let space = UIView(frame: CGRect(x: 0, y: 0, width: 8, height: 8)) let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) indicator.isUserInteractionEnabled = false indicator.startAnimating() let width = Int(label.frame.size.width + indicator.frame.size.width + space.frame.size.width) let view = UIStackView(arrangedSubviews: [indicator, space, label]) view.axis = .horizontal view.frame = CGRect(x: 20, y: 0, width: width, height: Int(heightConstraint.constant)) pending.view.addSubview(view) let widthConstraint:NSLayoutConstraint = NSLayoutConstraint(item: pending.view, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.greaterThanOrEqual, toItem: view, attribute: NSLayoutAttribute.width, multiplier: 1, constant: CGFloat(width)) pending.view.addConstraint(widthConstraint) self.present(pending, animated: true, completion: nil) return pending }


Apple no promueve la subclasificación directa de UIAlertController, así que hice una clase que muestra UIAlertController con UIActivityIndicator centrado y maneja la condición de cancelación con un protocolo de clase.

import Foundation import UIKit protocol BusyAlertDelegate { func didCancelBusyAlert() } class BusyAlert { var busyAlertController: UIAlertController? var presentingViewController: UIViewController? var activityIndicator: UIActivityIndicatorView? var delegate:BusyAlertDelegate? init (title:String, message:String, presentingViewController: UIViewController) { busyAlertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert) busyAlertController!.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "Cancel Button"), style: UIAlertActionStyle.Cancel, handler:{(alert: UIAlertAction!) in delegate?.didCancelBusyAlert() })) self.presentingViewController = presentingViewController activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) busyAlertController!.view.addSubview(activityIndicator!) } func display() { dispatch_async(dispatch_get_main_queue(), { self.presentingViewController!.presentViewController(self.busyAlertController!, animated: true, completion: { self.activityIndicator!.translatesAutoresizingMaskIntoConstraints = false self.busyAlertController!.view.addConstraint(NSLayoutConstraint(item: self.activityIndicator!, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.busyAlertController!.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)) self.busyAlertController!.view.addConstraint(NSLayoutConstraint(item: self.activityIndicator!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.busyAlertController!.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)) self.activityIndicator!.startAnimating() }) }) } func dismiss() { dispatch_async(dispatch_get_main_queue(), { self.busyAlertController?.dismissViewControllerAnimated(true, completion: nil) }) } }

Recomiendo usar var lazy para inicializar la clase.

lazy var busyAlertController: BusyAlert = { let busyAlert = BusyAlert(title: "Lengthy Task", message: "Please wait...", presentingViewController: self) busyAlert.delegate = self return busyAlert }()

Aquí hay un enlace al código de muestra: https://github.com/cgilleeny/BusyAlertExample.git


Asegúrese de establecer la propiedad de marco cuando está creando una vista.

func displaySignUpPendingAlert() -> UIAlertController { //create an alert controller let pending = UIAlertController(title: "Creating New User", message: nil, preferredStyle: .Alert) //create an activity indicator let indicator = UIActivityIndicatorView(frame: pending.view.bounds) indicator.autoresizingMask = [.flexibleWidth, .flexibleHeight] //add the activity indicator as a subview of the alert controller''s view pending.view.addSubview(indicator) indicator.isUserInteractionEnabled = false // required otherwise if there buttons in the UIAlertController you will not be able to press them indicator.startAnimating() self.presentViewController(pending, animated: true, completion: nil) return pending }

Para @ 62Shark:

let pending = UIAlertController(title: "Creating New User", message: nil, preferredStyle: .Alert) let indicator = UIActivityIndicatorView() indicator.setTranslatesAutoresizingMaskIntoConstraints(false) pending.view.addSubview(indicator) let views = ["pending" : pending.view, "indicator" : indicator] var constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[indicator]-(-50)-|", options: nil, metrics: nil, views: views) constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|[indicator]|", options: nil, metrics: nil, views: views) pending.view.addConstraints(constraints) indicator.userInteractionEnabled = false indicator.startAnimating() self.presentViewController(pending, animated: true, completion: nil)


Convertí la respuesta al Objetivo C, si alguien está interesado:

UIAlertController *pending = [UIAlertController alertControllerWithTitle:nil message:@"Please wait.../n/n" preferredStyle:UIAlertControllerStyleAlert]; UIActivityIndicatorView* indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; indicator.color = [UIColor blackColor]; indicator.translatesAutoresizingMaskIntoConstraints=NO; [pending.view addSubview:indicator]; NSDictionary * views = @{@"pending" : pending.view, @"indicator" : indicator}; NSArray * constraintsVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[indicator]-(20)-|" options:0 metrics:nil views:views]; NSArray * constraintsHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[indicator]|" options:0 metrics:nil views:views]; NSArray * constraints = [constraintsVertical arrayByAddingObjectsFromArray:constraintsHorizontal]; [pending.view addConstraints:constraints]; [indicator setUserInteractionEnabled:NO]; [indicator startAnimating]; [self presentViewController:pending animated:YES completion:nil];

Aclamaciones


En veloz

activityIndicator.center = self.view.center

Si tiene una barra de herramientas o un controlador de navegación, es posible que desee cambiar el punto, pero de lo contrario, el centro es el centro ...

Si todavía tienes problemas, quizás this tutorial te ayude. Si está intentando centrarlo en un controlador de vista de tabla, this respuesta podría ayudar.


La respuesta de @ petesalt convertida a Swift 3:

let pending = UIAlertController(title: "Saving, please wait...", message: nil, preferredStyle: .alert) let indicator = UIActivityIndicatorView() indicator.translatesAutoresizingMaskIntoConstraints = false pending.view.addSubview(indicator) let views = ["pending" : pending.view, "indicator" : indicator] var constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[indicator]-(-50)-|", options: NSLayoutFormatOptions.alignAllCenterY, metrics: nil, views: views) constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[indicator]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views) pending.view.addConstraints(constraints) indicator.isUserInteractionEnabled = false indicator.startAnimating() self.present(pending, animated: true, completion: nil)


Para aquellos como yo que prefieren UIActivityIndicatorView alineado a la izquierda de UIAlertController.title , esta es mi solución en Swift que funciona para todos los dispositivos:

let alert = UIAlertController(title: NSLocalizedString("Authenticating...", comment: "Authenticating"), message: nil, preferredStyle: .Alert); let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) activityIndicator.frame = activityIndicator.frame.rectByOffsetting(dx: 8, dy: (alert.view.bounds.height - activityIndicator.frame.height)/2); activityIndicator.autoresizingMask = .FlexibleRightMargin | .FlexibleTopMargin | .FlexibleBottomMargin activityIndicator.color = themeManager().currentTheme.navigationBarTintColor; activityIndicator.startAnimating(); alert.view.addSubview(activityIndicator); self.presentViewController(progressAlert, animated: true, completion: nil);

Sin embargo, para alinear UIActivityIndicatorView en el centro de la vista puede cambiar de la siguiente manera:

activityIndicator.center = CGPoint(x: (alert.view.bounds.width)/2, y: (alert.view.bounds.height)/2) activityIndicator.autoresizingMask = .FlexibleLeftMargin | .FlexibleRightMargin | .FlexibleTopMargin | .FlexibleBottomMargin


Prueba esto:

activityView.center = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height / 2.0)

También deberá verificar el modo horizontal y el ancho y alto inverso.

if(landscapeMode)activityView.center = CGPointMake(self.view.bounds.size.height/2.0, self.view.bounds.size.width / 2.0)

Tal vez usted puede obtener la posición de vista alerta?

alert.view.frame.origin.x alert.view.frame.origin.y

y usar eso para ubicar su vista de actividad dinámicamente, es decir, con las variables?

Por supuesto, es posible que también desee obtener la división de tamaño entre 2 y agregarla para que también se centre.

alert.view.frame.size.height alert.view.frame.size.width


Pues prueba este código.

UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"Creating new user/n/n/n" preferredStyle:UIAlertControllerStyleAlert]; UIActivityIndicatorView *loader = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; loader.center = CGPointMake(130.5, 65.5); loader.color = [UIColor blackColor]; [loader startAnimating]; [alert.view loader]; [self presentViewController:alert animated:NO completion:nil];


Tengo que implementar NSLayoutConstraint s para colocar el UIActivityIndicatorView en el centro del UIAlertController

Para Swift :

let loadingAlertController: UIAlertController = UIAlertController(title: "Loading", message: nil, preferredStyle: .alert) let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView(style: .gray) activityIndicator.translatesAutoresizingMaskIntoConstraints = false loadingAlertController.view.addSubview(activityIndicator) let xConstraint: NSLayoutConstraint = NSLayoutConstraint(item: activityIndicator, attribute: .centerX, relatedBy: .equal, toItem: loadingAlertController.view, attribute: .centerX, multiplier: 1, constant: 0) let yConstraint: NSLayoutConstraint = NSLayoutConstraint(item: activityIndicator, attribute: .centerY, relatedBy: .equal, toItem: loadingAlertController.view, attribute: .centerY, multiplier: 1.4, constant: 0) NSLayoutConstraint.activate([ xConstraint, yConstraint]) activityIndicator.isUserInteractionEnabled = false activityIndicator.startAnimating() let height: NSLayoutConstraint = NSLayoutConstraint(item: loadingAlertController.view, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 80) loadingAlertController.view.addConstraint(height); self.present(loadingAlertController, animated: true, completion: nil)

Resultado:


Tuve el mismo problema y usar el posicionamiento de cuadros no me funcionó. La respuesta de Yimin Lin fue muy cercana para mí, pero solo quería presentar una alternativa utilizando restricciones en formato no visual:

//... indicator.setTranslatesAutoresizingMaskIntoConstraints(false) alert.view.addSubview(indicator) alert.view.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: alert.view, attribute: attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)) alert.view.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: alert.view, attribute: attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)) //...