因為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:Intinit() {self.id = 0self.text = ""self.type = 0}
}
(2)創建畫中畫中顯示的view
//
// PIPSubtitleView.swift
//畫中畫中顯示的viewimport Foundationimport UIKit
import SnapKit
import SwiftUIclass PIPSubtitleView: UIView {//logo圖片private lazy var logoImageView: UIImageView = {let imageView = UIImageView()imageView.image = UIImage.init(systemName: "globe")return imageView}()//懸浮窗名稱labellazy var nameLabel: UILabel = {let label = UILabel()label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)label.textColor = UIColor.init(.black)label.adjustsFontSizeToFitWidth = truelabel.baselineAdjustment = .alignCentersreturn 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 = .centerlabel.textColor = UIColor.init(.black)label.font = UIFont.init(name: "DINAlternate-Bold", size: 12)label.adjustsFontSizeToFitWidth = truelabel.baselineAdjustment = .alignCenterslabel.numberOfLines = 0label.lineBreakMode =