iOS 启动页后广告Demo
重点!
对于启动页后的广告,相信大家也都看到过很多很多的,比如我自己常看到的有 QQ音乐,爱奇艺了。你点击了APP,它会启动就会随之启动。。其实这些APP的启动页是没有消失的,你去认真的观察一下!所以它们的顺序就变成了 点击 —> 启动页 —> 广告 下面是我截的QQ音乐的顺序图。不知道怎么弄GIF图。😊
为什么说这是重点呢,可能有些小伙伴会误以为使用广告替代了启动页,但启动页怎样做成一个广告呢,还要加一些点击时间之类的,很是不懂!现在就清楚了,至少知道它的一个流程才会有思路的。
还有一点,这个广告是缓存了的,你试着启动几次,它会给你不同的启动广告的,完事了,你把你的4G和Wifi都关掉,然后再去启动相应的APP,广告依旧是会出现的。。
一个思路:
这里我说我的一个思路:
1:把广告先封装到一个View当中去,然后把它加载到一个控制器当中显示,因为涉及到缓存和隐藏导航和标签栏的状况。
2:在 APPDelegate 的 didFinishLaunchingWithOptions 中进行一个根视图的切换(同志们看了下面代码分析要觉得有问题,欢迎指正)。
这里是广告View的.m文件代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #import "AdvertisingView.h" #import "UIImageView+WebCache.h" @interface AdvertisingView() @property ( nonatomic ,strong) UIImageView * advertisingView; @property ( nonatomic ,strong) UIButton * advertisingJumpButton; @property ( nonatomic ,strong) UILabel * timeLabel; @property ( nonatomic ,assign) int secondsCountDown; @property ( nonatomic ,strong) NSTimer * countDownTimer; /** 定时器(这里不用带*,因为dispatch_source_t就是个类,内部已经包含了*) */ @property ( nonatomic , strong) dispatch_source_t timer; @end @implementation AdvertisingView /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ -(instancetype) initWithFrame:(CGRect)frame { if ( self = [ super initWithFrame:frame]) { [ self addSubview: self .advertisingView]; [ self addSubview: self .advertisingJumpButton]; [ self addSubview: self .timeLabel]; } return self ; } -( void )startplayAdvertisingView:( void (^)(AdvertisingView *))advertisingview { [[UIApplication sharedApplication].keyWindow addSubview: self ]; [[UIApplication sharedApplication].keyWindow bringSubviewToFront: self ]; // 这里的block advertisingview ; // advertisingview(); 你要调用就要传参数过去,调用的具体代码在 APPdelegate 里面调用的时候添加这个 block具体的代码、、、 __block int count = 3; // 获得队列 dispatch_queue_t queue = dispatch_get_main_queue(); // 创建一个定时器(dispatch_source_t本质还是个OC对象) self .timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); // 设置定时器的各种属性(几时开始任务,每隔多长时间执行一次) // GCD的时间参数,一般是纳秒(1秒 == 10的9次方纳秒) // 何时开始执行第一个任务 // dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC) 比当前时间晚3秒 dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC )); uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC ); dispatch_source_set_timer( self .timer, start, interval, 0); // 设置回调 dispatch_source_set_event_handler( self .timer, ^{ /** * 回主线程更新UI */ count--; dispatch_async(dispatch_get_main_queue(), ^{ if (count == 0) { // 取消定时器 dispatch_cancel( self .timer); self .timer = nil ; [ self removeFromSuperview]; /** * 广告显示完,就调用 block 更换 rootcontroller */ advertisingview( self ); } else { _timeLabel.text = [ NSString stringWithFormat:@ "%d" ,count];} }); }); // 启动定时器 dispatch_resume( self .timer); } -(UIImageView * )advertisingView { if (_advertisingView == nil ) { _advertisingView =[[UIImageView alloc]initWithFrame: self .bounds]; [_advertisingView sd_setImageWithURL:[ NSURL URLWithString:@ "http://g.hiphotos.baidu.com/zhidao/pic/item/f2deb48f8c5494ee665ec00f29f5e0fe99257eac.jpg" ] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { }]; } return _advertisingView; } -(UILabel * )timeLabel { if (_timeLabel == nil ) { _timeLabel = [[UILabel alloc]initWithFrame:CGRectMake( self .bounds.size.width - 50, 50, 50, 40)]; _timeLabel.backgroundColor =[UIColor blackColor]; _timeLabel.alpha = 0.5; _timeLabel.textColor = [UIColor whiteColor]; } return _timeLabel; } -(UIButton * )advertisingJumpButton { if (_advertisingJumpButton == nil ) { _advertisingJumpButton = [UIButton buttonWithType:UIButtonTypeCustom]; _advertisingJumpButton.frame = CGRectMake(0, self .bounds.size.height - 80, self .bounds.size.width, 60); [_advertisingJumpButton setTitle:@ "了解详情" forState:UIControlStateNormal]; [_advertisingJumpButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [_advertisingJumpButton addTarget: self action: @selector (buttonclick) forControlEvents:UIControlEventTouchUpInside]; _advertisingJumpButton.titleLabel.font = [UIFont systemFontOfSize:18]; _advertisingJumpButton.backgroundColor = [UIColor blackColor]; _advertisingJumpButton.alpha = 0.5; _advertisingJumpButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; _advertisingJumpButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; } return _advertisingJumpButton; } -( void )buttonclick { } @end |
下面是添加这个View的控制器的.m文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #import "AdvertisingViewController.h" @interface AdvertisingViewController () @end @implementation AdvertisingViewController /** * 可以在这个控制器里面做缓存?爱奇艺,QQ音乐的广告是缓存了的! */ -( void )viewWillAppear:( BOOL )animated { [ self setNeedsStatusBarAppearanceUpdate]; } - ( BOOL )prefersStatusBarHidden { return YES ; } -( void )viewDidLoad { [ super viewDidLoad]; [ self .view addSubview: self .adverView]; } -(AdvertisingView *)adverView { if (_adverView == nil ) { _adverView = [[ AdvertisingView alloc]initWithFrame: self .view.bounds]; } return _adverView; } -( void )didReceiveMemoryWarning { [ super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ |
最重要的下面!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - ( BOOL )application:(UIApplication *)application didFinishLaunchingWithOptions:( NSDictionary *)launchOptions { self .window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self .window.backgroundColor = [UIColor whiteColor]; /** * 进来先让启动页沉睡 2 秒钟 */ [ NSThread sleepForTimeInterval:2.0]; [[UIApplication sharedApplication] setStatusBarHidden: NO withAnimation:UIStatusBarAnimationFade]; AdvertisingViewController * adviewcontroller = [[AdvertisingViewController alloc]init]; ZXTabBarController * tabbarcontroller = [[ZXTabBarController alloc]init]; // 这里要添加根控制器,不添加等下面添加是不行的。 self .window.rootViewController = adviewcontroller ; [ self .window makeKeyAndVisible]; [adviewcontroller.adverView startplayAdvertisingView:^(AdvertisingView * adverview) { // 更换根控制器 self .window.rootViewController = tabbarcontroller; }]; // Override point for customization after application launch. return YES ; } |
总结一下:
这样做,效果是实现了,但我心里一直的疑问就是在上面的更换根控制器这里,这样写效果是没问题的,下面我也会把效果图给大家看一下,本来这里我感觉就是这整个效果的一个核心的地方,大家要觉得有问题。。欢迎来撩!!要是你喜欢的话。。哈哈哈 这里有我的QQ可以联系到我
最后的效果图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话