SwiftUI应用开屏广告界面(3秒跳转)
作者:互联网
SwiftUI应用开屏广告界面(3秒跳转)
瞎扯
最近开始玩Swift试试macOS和iOS开发
我都快忘了我是啥专业的了
不想看我瞎扯可以直接跳到这
需求
模拟开屏广告的模式,为应用做一个开屏活动页,远端提供活动页图片;
图片经过3s倒计时后消失,用户可以点击“跳过”按钮提前结束;
源码
废话不多说,先直接上源码。
工程中只修改了ContentView.swift文件,所以这里只放ContentView.swift的代码:
//
// ContentView.swift
// iOSTest
//
// Created by WMIII on 2021/3/21.
//
import SwiftUI
import UIKit
import Combine
class TimeHelp {
var canceller: AnyCancellable?
//每次都新建一个计时器
func start(receiveValue: @escaping (() -> Void)) {
let timerPublisher = Timer
.publish(every: 1, on: .main, in: .common)
.autoconnect()
self.canceller = timerPublisher.sink { date in
receiveValue()
}
}
//暂停销毁计时器
func stop() {
canceller?.cancel()
canceller = nil
}
}
struct ContentView: View {
@State private var remoteImage :UIImage? = nil
@State var isPresented = false
let placeholderOne = UIImage(named: "Image1")
// 这里的Image1为工程资源文件夹中的图片资源名,自己随便创建一个就行
let timer = Timer.publish(every: 1, on: .main, in: .common)
@State private var second = 5
private let timeHelper = TimeHelp()
@State private var end = true
var body: some View {
ZStack
{
Button("跳过 \(second)"){
self.isPresented = true
}
.position(x: UIScreen.main.bounds.width - 45, y: 10.0)
.onAppear()
{
guard self.end else {return}
self.end = false
self.second = 3
self.timeHelper.start {
// print(second)
if self.second > 1 {
_ = self.second -= 1
}else{
//暂停
self.end = true
self.timeHelper.stop()
self.isPresented = true
}
}
}
.fullScreenCover(isPresented: $isPresented) {
print("消失")
} content: {
DetailView(message: "I'm missing you")
}
Image(uiImage: self.remoteImage ?? placeholderOne!)
// Image(uiImage: self.placeholderOne!)
.resizable()
.scaledToFit()
// .aspectRatio(contentMode: .fill)
.onAppear(perform: fetchRemoteImg)
}
}
func fetchRemoteImg()
{
guard let url = URL(string: "https://store.storeimages.cdn-apple.com/8756/as-images.apple.com/is/iphone-12-pro-family-hero?wid=940&hei=1112&fmt=jpeg&qlt=80&.v=1604021663000") else {return}
URLSession.shared.dataTask(with: url)
{
(data, response, error) in
if let img = UIImage(data: data!)
{
self.remoteImage = img
}
else
{
print(error ?? "1")
}
}
.resume()
}
}
struct DetailView: View{
let message: String
var body: some View {
VStack
{
Text(message)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
思路分析
由于我刚入门Swift,学艺不精,而且目前SwiftUI的教程比较少,所以有些地方的代码我是直接借(c)鉴(v)别处的,并且我也不能很好的理解。
页面跳转
从开屏广告页回到应用界面的思路,我找到两种:将广告界面贴在主界面上,然后删除;或者通过页面跳转。
虽说贴界面可以通过ZStack,但是我并不会在SwiftUI中删除页面,所以我选择页面跳转的方式。
目前各大博客平台能搜索到的SwiftUI界面跳转方法都是用NavigationView,NavigationLink等方式;虽说简单,但是这种方式不符合我的需求:通过以上方式跳转到的界面左上角会自带一个“返回”按钮,而且页面还会有页眉。
找来找去,发现一个通过fullScreenCover来进行页面跳转的方式。
参考:https://blog.csdn.net/u011146511/article/details/113763403
目前我并没有找到解释fullScreenCover的(中文)API文档;并且这名字听起来貌似也是将一个页面覆盖在原页面上…
// ContentView.swift
import SwiftUI
struct ContentView:View {
@State var isPresented = false
var body: some View{
Button("present"){
self.isPresented = true
}.fullScreenCover(isPresented: $isPresented) {
} content: {
DetailView()
}
}
}
struct DetailView: View{
var body: some View {
VStack
{
Text("It's a beautiful night.")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
点击时将isPresented置为true,然后fullScreenCover就将content中的DetailView展现在界面中。
计时
要求中需要3s的倒计时,所以需要用到SwiftUI中的Timer,所以我们把定时器添加到前面的代码中,同时将本地的一个测试图片显示到界面中,并做一些排版。
参考:https://www.jianshu.com/p/66b9ad87695c
// ContentView.swift
import SwiftUI
import UIKit
import Combine
class TimeHelp {
var canceller: AnyCancellable?
//每次都新建一个计时器
func start(receiveValue: @escaping (() -> Void)) {
let timerPublisher = Timer
.publish(every: 1, on: .main, in: .common)
.autoconnect()
self.canceller = timerPublisher.sink { date in
receiveValue()
}
}
//暂停销毁计时器
func stop() {
canceller?.cancel()
canceller = nil
}
}
struct ContentView: View {
@State var isPresented = false
let placeholderOne = UIImage(named: "Image1")
let timer = Timer.publish(every: 1, on: .main, in: .common)
@State private var second = 5
private let timeHelper = TimeHelp()
@State private var end = true
var body: some View {
ZStack
{
Button("跳过 \(second)"){
self.isPresented = true
}
.position(x: UIScreen.main.bounds.width - 45, y: 10.0)
.onAppear()
{
guard self.end else {return}
self.end = false
self.second = 3
self.timeHelper.start {
// print(second)
if self.second > 1 {
_ = self.second -= 1
}else{
//暂停
self.end = true
self.timeHelper.stop()
self.isPresented = true
}
}
}
.fullScreenCover(isPresented: $isPresented) {
} content: {
DetailView()
}
Image(uiImage:placeholderOne!)
.resizable()
.scaledToFit()
.onAppear(perform: fetchRemoteImg)
}
}
}
struct DetailView: View{
var body: some View {
VStack
{
Text("It's a beautiful night.")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
远程图片获取
在ContentView中添加如下函数:
func fetchRemoteImg()
{
guard let url = URL(string: "https://store.storeimages.cdn-apple.com/8756/as-images.apple.com/is/iphone-12-pro-family-hero?wid=940&hei=1112&fmt=jpeg&qlt=80&.v=1604021663000") else {return}
// 这里的string为图片的地址,这里我用的是Apple官网商店的图片
URLSession.shared.dataTask(with: url)
{
(data, response, error) in
if let img = UIImage(data: data!)
{
self.remoteImage = img
}
else
{
print(error ?? "1")
}
}
.resume()
}
在ContentView中添加一行属性:
@State private var remoteImage :UIImage? = nil
同时将ContentView中的Image控件更改为:
// 如果未获取到远端图片,则显示本地默认图片
Image(uiImage: self.remoteImage ?? placeholderOne!)
.resizable()
.scaledToFit()
.onAppear(perform: fetchRemoteImg)
更改完成之后就可以实现需求功能了。
标签:ContentView,self,开屏,SwiftUI,跳转,var,let,isPresented,View 来源: https://blog.csdn.net/weixin_46068920/article/details/115406957