iOS(swiftui)——系统悬浮窗( 可在其他应用上显示,可实时更新内容)

因为ios系统对权限的限制是比较严格的,ios系统本身是不支持全局悬浮窗(可在其他app上显示)。在iphone14及之后的iPhone机型中提供了一个叫 灵动岛的功能,可以在手机上方可以添加一个悬浮窗显示内容并实时更新,但这个功能有很多局限性

如:需要iPhone14及之后的机型且系统必须是iOS16.1+,在以后的新机型中还有没有这个功能也还不明确,样式和位置固定。

在ios系统中现有的,应用成熟的功能中,画中画是唯一可以在全局显示的悬浮窗,但画中画中针对视频。那我们就需要将我们想展示的内容放到视频中展示。
 

效果如下:

  

1. 环境

iso14+
本文使用code14.2

2. 配置

在项目target中配置Background Modes 勾选Audio,AirPlay,and Picture in Picture 项

在Info.plist文件中添加如下

3. 代码

(1)定义一个悬浮窗信息的model类

import Foundation
/**
 继承ObservableObject,使用Published 发布 text 等,这样当infoMode发生变化时,所有订阅infoMode的订阅者都能收到通知
 */
class InfoModel: ObservableObject {
    @Published var id:Int
    @Published var text:String
    @Published var type:Int
    init() {
        self.id = 0
        self.text = ""
        self.type = 0
    }
}

(2)创建画中画中显示的view

//
//  PIPSubtitleView.swift
//画中画中显示的view

import Foundation

import UIKit
import SnapKit
import SwiftUI

class PIPSubtitleView: UIView {
    //logo图片
    private lazy var logoImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage.init(systemName: "globe")
        return imageView
    }()
    //悬浮窗名称label
    lazy var nameLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
        label.textColor = UIColor.init(.black)
        label.adjustsFontSizeToFitWidth = true
        label.baselineAdjustment = .alignCenters
        return label
    }()
    //内容左侧图片
    private lazy var leftimg: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit // 设置内容模式适应视图的大小
        imageView.image = UIImage.init(named: "getnew.jpge")
        return imageView
    }()
    lazy var textLabel: UILabel = createSubTextLable()
    
    func createSubTextLable() ->UILabel{
        let label = UILabel()
        label.textAlignment = .center
        label.textColor = UIColor.init(.black)
        label.font = UIFont.init(name: "DINAlternate-Bold", size: 12)
        label.adjustsFontSizeToFitWidth = true
        label.baselineAdjustment = .alignCenters
        label.numberOfLines = 0
        label.lineBreakMode =
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS开发中,可以通过以下两种方式来让应用在一定时长后后台关闭: 1. 使用 Timer 可以在应用启动后使用 Timer 定时器来计算应用运行的时长,当运行时间超过设定的时间后,就可以通过调用 UIApplication 的 `beginBackgroundTask(withName:expirationHandler:)` 方法来申请后台任务,然后在后台任务中调用 `UIApplication.shared.perform(#selector(NSXPCConnection.suspend))` 方法来让应用进入后台并关闭。 示例代码: ``` private var timer: Timer? private var backgroundTask: UIBackgroundTaskIdentifier = .invalid func startTimer() { timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [weak self] _ in guard let self = self else { return } let runTime = Date().timeIntervalSince(self.startTime) if runTime > 3600 { // 超过1小时 self.stopTimer() self.backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "CloseAppInBackground") { self.endBackgroundTask() } UIApplication.shared.perform(#selector(NSXPCConnection.suspend)) } } } func stopTimer() { timer?.invalidate() timer = nil } func endBackgroundTask() { UIApplication.shared.endBackgroundTask(backgroundTask) backgroundTask = .invalid } ``` 2. 使用 DispatchAfter 可以在应用启动后使用 GCD 的 `DispatchQueue.asyncAfter(deadline:)` 方法来延迟一定时间后执行关闭应用的操作,然后在应用进入后台时调用 `UIApplication.shared.perform(#selector(NSXPCConnection.suspend))` 方法来让应用进入后台并关闭。 示例代码: ``` private var closeAppWorkItem: DispatchWorkItem? func scheduleCloseApp() { let deadline = DispatchTime.now() + 3600 closeAppWorkItem = DispatchWorkItem { UIApplication.shared.perform(#selector(NSXPCConnection.suspend)) } DispatchQueue.main.asyncAfter(deadline: deadline, execute: closeAppWorkItem!) } func cancelCloseApp() { closeAppWorkItem?.cancel() } ``` 以上是两种让应用在一定时长后后台关闭的方法,开发者可以根据自己的需求选择合适的方法来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值