iOS实现多个弹框按顺序依次弹出效果

有时候会有这样的需求:App 运行完,加载 RootVC ,此时需要做一些操作,比如检查更新,之类的。此时可能会需要有2个甚至多个弹框依次弹出。

本篇将以系统的 UIAlertController 作为示例,当然,如果是自定义的,也要看一下这篇文章,如何来处理多个弹窗。

首先,如果就按照如下的默认写法:

- (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"弹框1" message:@"第一个弹框" preferredStyle:UIAlertControllerStyleAlert];
 [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
 [self presentViewController:alert animated:YES completion:nil];

 UIAlertController *alert2 = [UIAlertController alertControllerWithTitle:@"弹框2" message:@"第二个弹框" preferredStyle:UIAlertControllerStyleAlert];
 [alert2 addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
 [self presentViewController:alert2 animated:YES completion:nil];
}

会有什么问题呢?注意控制台,肯定会输出

Warning: Attempt to present <UIAlertController: 0x7ff4c3078c00>  on <SCTestViewController: 0x7ff4c2718c20> which is already presenting <UIAlertController: 0x7ff4c283ae00>

所以说,第二个弹框应该是看不到的。

另一种情况,如果是自定义的 Alert ,你把它 add 为 window 的子视图,这么做第二个弹框会盖在第一个上面。如果你用了毛玻璃背景,效果会更加明显。肯定不合适了。

所以,正确的解决办法就是类似加锁的过程,当点击了第一个弹框的某个按钮之后,再弹出第二个弹框,以此类瑞。

这里,我想到用信号量去解决,但是信号量会阻塞线程,不可以直接在主线程使用。所以我们需要在子线程控制信号量,在主线程创建和显示 Alert,直接上代码。

- (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 //创建一个队列,串行并行都可以,主要为了操作信号量
 dispatch_queue_t queue = dispatch_queue_create("com.se7en.alert", DISPATCH_QUEUE_SERIAL);
 dispatch_async(queue, ^{
  //创建一个初始为0的信号量
  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  //第一个弹框,UI的创建和显示,要在主线程
  dispatch_async(dispatch_get_main_queue(), ^{
   UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"弹框1" message:@"第一个弹框" preferredStyle:UIAlertControllerStyleAlert];
   [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    //点击Alert上的按钮,我们发送一次信号。
    dispatch_semaphore_signal(sema);
   }]];
   [self presentViewController:alert animated:YES completion:nil];
  });

  //等待信号触发,注意,这里是在我们创建的队列中等待
  dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  //上面的等待到信号触发之后,再创建第二个Alert
  dispatch_async(dispatch_get_main_queue(), ^{
   UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"弹框2" message:@"第二个弹框" preferredStyle:UIAlertControllerStyleAlert];
   [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    dispatch_semaphore_signal(sema);
   }]];
   [self presentViewController:alert animated:YES completion:nil];
  });

  //同理,创建第三个Alert
  dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  dispatch_async(dispatch_get_main_queue(), ^{
   UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"弹框3" message:@"第三个弹框" preferredStyle:UIAlertControllerStyleAlert];
   [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    dispatch_semaphore_signal(sema);
   }]];
   [self presentViewController:alert animated:YES completion:nil];
  });
 });
}

如此一来,就实现了我们的需求。

需要注意的是,这里为什么不用全局并发队列,主要是考虑到信号量会阻塞线程,优先级特别高,如果此时队列中还有任务,那么就会等待信号触发。当然也有人故意这么做。对于 “弹框弹出的时间,不要做其他任何事情” 这种需求是很合适的。当然我们千万不能去阻塞主线程!

我们在异步线程等待信号,在主线程发信号,如此就可以实现两个线程同步。其实信号量就是一种锁。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS自定义提示弹出框实现类似UIAlertView的效果

    首先来看看实现的效果图 下面话不多说,以下是实现的示例代码 #import <UIKit/UIKit.h> typedef void(^AlertResult)(NSInteger index); @interface XLAlertView : UIView @property (nonatomic,copy) AlertResult resultIndex; - (instancetype)initWithTitle:(NSString *)title message:(NSString

  • ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)

    在使用ionic开发IOS系统微信的时候会有一个苦恼的问题,填写表单的时候键盘会挡住输入框,其实并不算什么大问题,只要用户输入一个字就可以立刻看见输入框了. 可惜的是,有些客户是不讲理的,他才不管这个问题,反正就是不行,所以在一天睡觉的时候突然惊醒,想出来这个方案. 我就不仔细讲代码了,直接上图 angular.module('MyApp') .directive('focusInput', ['$ionicScrollDelegate', '$window', '$timeout', '$io

  • iOS中你需要的弹窗效果总结大全

    前言 弹框是人机交互中常见的方式,常常出现于询问.警示以及完成某个插入任务,常见于网页端及移动端.弹框能使用户有效聚焦于当前最紧急的信息,也可以在不用离开当前页面的前提下,完成一些轻量的任务. 在我们的实际开发项目中,弹窗是必不可少的,很多时候我们用的是系统的AlertViewController,但是实际情况中,并不能满足我们的开发需求,这个时候我们需要的就是自定义自己的弹窗效果.接下来我会写一些自己的所封装的弹窗效果.包括代理delegate回调,block 回调,xib新建view来创建我

  • iOS项目开发键盘弹出遮挡输入框问题解决方案

    在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发过程中,一般用于进行输入信息的有两类:UITextField和UITextView,前者是单行输入文本框,后者是可滑动的多行输入文本框,在这整个开发过程中,我们需要控制键盘的弹出和收起.在输入结束的时候获取输入的信息,此外,我们还需要保证在键盘弹起的时候不遮挡我们输入的文本框.今天,我们就主要来说一

  • IOS中Swift仿QQ最新版抽屉侧滑和弹框视图

    导读 简单用Swift写了一个抽屉效果,可以直接使用并且简单; 很多软件都运了抽屉效果,比如qq的左抽屉,英雄联盟,滴滴打车,和uber等等都运用了抽屉; 效果 iOS抽屉式结构实现分析 主要是在控制器的View上添加了两个View,一个左侧leftView和一个mainView.这里我们自定义一个DrawerViewController,init(mainVC: UIViewController, leftMenuVC: UIViewController, leftWidth: CGFloat

  • IOS 中弹框的实现方法整理

    IOS 中弹框的实现方法整理 #define iOS8Later ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) ios 8以前的弹框 @interface RootViewController ()<UIAlertViewDelegate> @end UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"登陆失败" message:

  • 详谈iOS 位置权限弹出框闪现的问题

    当编码如下的时候,进入页面的时候可以看到UIAlertView弹出框出现一下,刚想点击的时候,他不见了,这个郁闷 CLLocationManager* _locationManager = [[CLLocationManager alloc] init]; _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; if ([[UIDevice currentDevice].systemVersion floatVal

  • iOS实现多个弹框按顺序依次弹出效果

    有时候会有这样的需求:App 运行完,加载 RootVC ,此时需要做一些操作,比如检查更新,之类的.此时可能会需要有2个甚至多个弹框依次弹出. 本篇将以系统的 UIAlertController 作为示例,当然,如果是自定义的,也要看一下这篇文章,如何来处理多个弹窗. 首先,如果就按照如下的默认写法: - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; UIAlertController *alert =

  • Vue自定义render统一项目组弹框功能

    一.本文收获 pick 二.为什么要统一封装弹框: 要封装成怎样 通过举例常规弹框的写法.我们可以体会到,通常要弹出一个页面,需要创建一个页面 normalDialog.vue 包裹 dialogBody.vue (弹框主体):需要 parent.vue 设置flag控制弹框显示隐藏, normalDialog.vue 关闭的时候设置 parent.vue 对应 flag .缺点: 流程繁杂.配置繁琐.不灵活.样式不统一和参数传递麻烦等 .如果一个项目弹框较多的时候,弊端将会更明显,大量的 is

  • vue多种弹框的弹出形式的示例代码

    1.父组件引入子组件,子组件的加载问题 products.vue引入dlAddProd弹框(dlAddProd.vue),由于<div v-show="visible">,所以在products页面加载时,dlAddProd会被加载.但是el-dialog中的body部分不会被加载(不管有没有加v-if指令):dlAddProd弹框中又引入了dlBlankAdd弹框和dlEditProd弹框,但此时只有dlBlankAdd会被加载,dlEditProd不会被加载(<d

  • React Native实现进度条弹框的示例代码

    本文介绍了React Native实现进度条弹框,分享给大家 我们在上传或者下载文件时候,希望有一个进度条弹框去提醒用户取当前正在上传或者下载,也允许用去取点击取消上传或者下载. 首先实现进度条. import React, { PureComponent } from 'react'; import { StyleSheet, View, Animated, Easing, } from 'react-native'; class Bar extends PureComponent { con

  • 基于jquery实现的一个选择中国大学的弹框 (数据、步骤、代码)

    1. 数据 一共包含了全国3049所大学, 从人人网拷贝的 (仅供学习交流, 请勿用于商业项目), 这是一个脚本文件, 里含的JSON对象存储了学校的信息, 格式为: 复制代码 代码如下: var schoolList=[ { "id":1, //省份id "school": [ { "id": 1001, //学校id "name": "\u6e05\u534e\u5927\u5b66" //学校名称 }

  • 浅析Android中常见三种弹框在项目中的应用

    一丶概述 弹框在Android项目中经常出现,常见的实现方法有三种:Dialog 弹框,Window弹框,Activity伪弹框.本文就说一说三种弹框的实现及在项目中的运用. 二丶演示图         图一为常见的三种弹框(文末上链接),图二为项目中用到的Activity伪弹框 三丶正文 1.Dialog弹框 先看一篇一篇文章: android 8种对话框(Dialog)使用方法汇总 Dialog是系统自带的弹框,然而常常因为UI不好看而遭嫌弃,常需要自定义 public class MyDi

  • Android 提交或者上传数据时的dialog弹框动画效果

    效果图如下所示: 类似这种弹框里含有动画,一般我们在上传数据或者支付的时候会用到,当然,假如我们换几张图片,还可以把它当做是加载数据的时候使用,总之这是一个dialog弹框,只不过这个弹框在弹出后,上面有动画的运行. 上代码 首先是布局文件 : <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="200dp" andr

  • vue+iview写个弹框的示例代码

    iView 是一套基于Vue.js的开源UI组件库,主要服务于PC界面的中后台产品. 1.iView的特性 1) 高质量.功能丰富 2) 友好的API ,自由灵活地使用空间 3) 细致.漂亮的 UI 4) 事无巨细的文档 5) 可自定义主题 2.iView的安装: 1) 使用npm: npm install --save iview 2) CDN引入: <link rel="stylesheet" href="css/iview.css" rel="

  • vue项目中仿element-ui弹框效果的实例代码

    最近要写个弹框,发现element-ui弹框样式还可以,就copy下来改吧改吧.也不分步骤详细介绍了直接上代码. 在组件目录中新建文件夹message 我把message目录里的东西给大家贴出来 message文件夹 src文件夹 index.js import Message from './src/main.js'; export default Message; mian.js import Vue from 'vue'; import Main from './main.vue'; le

  • 通过vue.extend实现消息提示弹框的方法记录

    前提回顾 在项目开发中我们经常使用的组件注册分为两种,一个是全局注册和另一个是局部注册,假设我们的业务场景是用户在浏览注册页面时,点击页面中的注册按钮后,前端根据用户的注册信息先做一次简单的验证,并根据验证弹出一个对应消息提示弹框 我们拿到这个需求后,便开始着手准备要通过局部注册消息弹框组件的方法来实现这个场景,在通过局部注册消息弹框组件的方法解决完这个需求后,自然是沾沾自喜,紧接着又迎来了一个需求,该需求是用户在点击该注册按钮时,点击几次就要出现几次这个消息弹框,你开始犯了难,并思考难道我要在

随机推荐