iOS16灵动岛横屏视频播放适配(ZFPlayer)

news2025/5/29 7:33:33

项目场景:

手机为iphone14Pro
版本iOS16.0.3
Xcode版本14.2
视频播放第三方库ZFPlayer


问题描述

使用视频时,视频播放自动横屏控制层的返回按钮和暂停按钮都点不到,上图错误、下图正确(控制按钮距离屏幕左右减小50、视频全屏不做改变)
在这里插入图片描述
在这里插入图片描述


原因分析:

  1. 全屏没有考虑灵动岛的范围,这里在屏幕旋转时重置控制层View的frame,全局持有ZFPlayerControlView控制层,将控制层左右缩小合适距离,我这里取得50

    self.controlView.frame = CGRectMake(50, 0, AKScreenHeight-100, AKScreenWidth);
    
  2. 注意在旋转回去时需要将高宽重置回去,重置相对于父容器的,所以是

    CGRectMake(0, 0, self.videoContainerView.width, self.videoContainerView.height)
    

解决方案:

关键代码:

self.playerControlView.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen){
        @strongify(self);

        dispatch_async(dispatch_get_main_queue(), ^{
            if(@available(iOS 16.0, *)){
                if(isFullScreen){
                    self.controlView.frame = CGRectMake(50, 0, AKScreenHeight-100, AKScreenWidth);
                }else{
                    self.controlView.frame = CGRectMake(0, 0, self.videoContainerView.width, self.videoContainerView.height);
                }
            }
        });

    };

全部代码:


#import "ZFAVPlayerManager.h"
#import "ZFPlayerController.h"


//===================

@property (nonatomic, strong) UIView *shadowView;
@property (nonatomic, strong) UIButton *playButton;
@property (nonatomic, strong) UIImageView *mainImageView;

@property (nonatomic ,strong) UIView *videoContainerView;
@property (nonatomic, strong) NSString *mediaUrl;
@property (nonatomic, strong) UILabel *tips4GLabel;

@property (nonatomic, strong) ZFPlayerController *playerControlView;//视频播放器
@property (nonatomic, strong) ZFAVPlayerManager *playerManager;
@property (nonatomic, strong) ZFPlayerControlView *controlView;

//===================

- (void)showVedioView{
    
    self.mediaUrl =@"http://xxxxx.mp4";//视频
    
    self.videoContainerView = [UIView new];
    self.videoContainerView.layer.cornerRadius = 4;
    [self.view addSubview:self.videoContainerView];

    
    self.mainImageView = [UIImageView new];
    [self.view addSubview:self.mainImageView];
    self.mainImageView.layer.cornerRadius = 4;
    self.mainImageView.clipsToBounds = YES;
    self.mainImageView.userInteractionEnabled = YES;
    self.mainImageView.contentMode = UIViewContentModeScaleAspectFill;
    self.mainImageView.hidden = NO;
    
    
    self.playerManager = [[ZFAVPlayerManager alloc] init];
    
    self.playerManager.scalingMode = ZFPlayerScalingModeAspectFit;
    /// 播放器相关
    self.playerControlView = [ZFPlayerController playerWithPlayerManager:self.playerManager containerView:self.videoContainerView];
    self.playerControlView.shouldAutoPlay = NO;
    self.playerControlView.pauseByEvent = YES;
    
    ZFPlayerControlView *controlView = [ZFPlayerControlView new];
    controlView.fastViewAnimated = YES;
    controlView.prepareShowLoading = YES;

    self.playerControlView.controlView = controlView;
    self.controlView = controlView;
    
    UIView *shadowView = [UIView new];
    shadowView.userInteractionEnabled = YES;
    [self.mainImageView addSubview:shadowView];
    shadowView.backgroundColor = ColorHexAlpha(@"#000000", 0.4);
    
    
    self.playButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.mainImageView addSubview:self.playButton];
    [self.playButton setImage:[UIImage imageNamed:@"vedio_start_icon"] forState:UIControlStateNormal];
    
    @weakify(self);
    [[self.playButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        @strongify(self);
        self.playerControlView.assetURL = [NSURL URLWithString:self.mediaUrl];
        self.mainImageView.hidden = YES;
        self.videoContainerView.hidden = NO;
        self.playButton.hidden = YES;
        
        [self.playerControlView.currentPlayerManager play];
        self.playerControlView.playerLoadStateChanged = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, ZFPlayerLoadState loadState) {
        };
        
        
    }];
    
    
    self.playerControlView.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
        @strongify(self);
        
    };
    
    
    [self.playerControlView setPlayerDidToEnd:^(id<ZFPlayerMediaPlayback>  _Nonnull asset) {
        @strongify(self);
        self.mainImageView.hidden = NO;
        self.playButton.hidden = NO;
        self.videoContainerView.hidden = YES;
    }];
    
    self.playerControlView.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen){
        @strongify(self);

        dispatch_async(dispatch_get_main_queue(), ^{
            if(@available(iOS 16.0, *)){
                if(isFullScreen){
                    self.controlView.frame = CGRectMake(50, 0, AKScreenHeight-100, AKScreenWidth);
                }else{
                    self.controlView.frame = CGRectMake(0, 0, self.videoContainerView.width, self.videoContainerView.height);
                }
            }
        });

    };

   
    
    [self.videoContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(@16);
        make.right.equalTo(@(-16));
        make.top.equalTo(self.view).offset(323*FTGetScreenScale());
        make.height.offset(175*FTGetScreenScale());
    }];

    [self.mainImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.bottom.mas_equalTo(self.videoContainerView);
    }];
    
    [shadowView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.bottom.equalTo(@0);
    }];
    
    [self.playButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.mainImageView);
        make.top.equalTo(self.mainImageView.mas_top).offset(85*FTGetScreenScale());
        make.width.equalTo(@(92*FTGetScreenScale()));
        make.height.equalTo(@(23*FTGetScreenScale()));
    }];
    
    
    UILabel *label = [[UILabel alloc] init];
    label.frame = CGRectMake(61, 432, 252, 20);
    [self.mainImageView addSubview:label];
    NSMutableAttributedString *string = [
      [NSMutableAttributedString alloc] initWithString:@"当前为非无线网络环境,请注意流量消耗"
      attributes: @{
        NSFontAttributeName: [UIFont fontWithName:@"PingFangSC-Medium" size: 14*FTGetScreenScale()],
        NSForegroundColorAttributeName: [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.00],
    }];
    label.attributedText = string;
    label.textAlignment = NSTextAlignmentLeft;
    self.tips4GLabel = label;
    NSInteger status = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).networkStatus;
	 if (status == 1) {
        // 流量提示
        self.tips4GLabel.hidden = NO;
        self.playButton.hidden = NO;
    }else{
        self.tips4GLabel.hidden = YES;
        self.playerControlView.assetURL = [NSURL URLWithString:self.mediaUrl];
        self.mainImageView.hidden = YES;
        self.videoContainerView.hidden = NO;
        self.playButton.hidden = YES;
        
        [self.playerControlView.currentPlayerManager play];
    }
    
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.mainImageView);
        make.top.equalTo(self.mainImageView.mas_top).offset(52.5*FTGetScreenScale());
        make.width.equalTo(@(252*FTGetScreenScale()));
        make.height.equalTo(@(20*FTGetScreenScale()));
    }];
    
}

oc版本的,Swift请自己再转一下。也有新push到另一个控制层进行播放的,因为需要小屏和全屏播放更丝滑一点,没有采用另一个方案.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/334835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Maven:基础知识

Maven概念图生命周期目录工程创建测试常用命令COMPILATION ERROR : 不再支持目标选项 5。请使用 7 或更高版本。问题解决pom.xml文件properties配置示例scope配置详解概念图 依赖管理构建项目Maven 的底层核心实现项目的构建和管理必须通过插件完成&#xff0c;但插件本身并不包…

VC++打开或关闭目标进程的声音(扬声器)(附源码)

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

一刷代码随想录——单调栈

每日温度739题目描述&#xff1a;给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来…

spring security 核心类 和请求登陆过程

核心类图2. 执行登陆 首先请求被拦截器 UsernamePasswordAuthenticationFilter 拦截 看源代码可以看出默认拦截的是 /login 请求地址 当然这个地址是可以被配置的 private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER new AntPathRequestMatche…

DFS深度优先算法 —— AcWing 842. 排列数字AcWing 843. n-皇后问题

一、了解dfs1、DFS&#xff08;Depth First Search&#xff09;DFS在我看来就是一条路走到黑&#xff0c;直到无路可走的情况下&#xff0c;才会选择回头&#xff0c;然后重新选择一条路&#xff08;官方说法即“优先考虑深度”&#xff09;整个进程反复进行直到所有节点都被访…

Allegro如何添加ICT操作指导

Allegro如何添加ICT操作指导 当PCB板需要做飞针测试的时候,通常需要在PCB设计的时候给需要测试的网络添加上ICT。 如图: Allegro支持给网络添加ICT,具体操作如下 首先在库中创建一个阻焊开窗的过孔,比如via10-ict一般阻焊开窗的尺寸比盘单边大2mil 在PCB中选择Manufacture…

Linux基础命令1(常见的系统进程、状态命令)

目录 Linux命令格式 Linux快捷按键 常用系统命令 man 查看命令的帮助信息 echo 输出信息&#xff08;将信息输出到屏幕上面&#xff09; date 查看系统的日期、时间 timedatectl 设置系统时间&#xff0c;主要是时区&…

程序环境--翻译+执行

ANSI C标准下&#xff0c;有两种程序环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 翻译环境包括&#xff1a;预处理&#xff08;预编译&#xff09;编译汇编链接。四个步骤。 第2种是执行/运行环境&#xff0c;它用于实际执行代码。 链接…

UPC-2023新生个人训练赛第18场-Rank1

问题 B: 2的N次方 题目描述 输入n行&#xff0c;每行一个整数x&#xff0c;输出2的x次方的个位是多少&#xff1f;2的3次方表示3个2相乘&#xff0c;结果是8 输入 输入n行&#xff0c;每行一个整数x 输出 输出n行&#xff0c;每行一个整数&#xff0c;2的x次方的个位。 …

Flink CEP 在抖音电商的业务实践

摘要&#xff1a;本文整理自抖音电商实时数仓研发工程师张健&#xff0c;在 FFA 实时风控专场的分享。本篇内容主要分为四个部分&#xff1a;Flink CEP 简介业务场景与挑战解决方案实践未来展望Tips&#xff1a;点击「阅读原文」查看原文视频&演讲 ppt01Flink CEP 简介Flin…

论文投稿指南——中文核心期刊推荐(冶金工业 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

23种设计模式之策略模式

一、概念 就是将一系列算法封装起来&#xff0c;并使它们之间相互替换。被封装起来的算法具有独立性外部不可改变其特性。 策略模式属于对象行为模式&#xff0c;它通过对算法进行封装&#xff0c;把使用算法的责任和算法的实现分割开来&#xff0c;并委派给不同的对象对这些算…

BCN点击试剂diSulfo-Cy5-PEG3-BCN,二磺酸三聚乙二醇环丙烷环辛炔,纯度 95%+

【中文名称】二磺酸-三聚乙二醇-环丙烷环辛炔【英文名称】 diSulfo-Cy5-PEG3-BCN&#xff0c;BCN-PEG-Sulfo Cy5【CAS号】N/A【分子式】C51H68N4O12S2【分子量】993.24【基团】BCN基团【纯度】95%【规格标准】1g&#xff0c;5g&#xff0c;10g&#xff0c;包装灵活&#xff0c;…

2-ChatGPT插件到Google浏览器,并进行ChatGPT工作。

ChatGPT插件到Google浏览器&#xff0c;并进行ChatGPT工作。1&#xff0c;首先&#xff0c;在装插件ChatGPT forGoogle插件时&#xff0c;我没安装成功&#xff0c;问题是我没有区分Google浏览器和双核浏览器的差别。2&#xff0c;如何使用ChatGPT在浏览器上进行工作。1&#x…

[future 2022] 基于特征选择的DDoS攻击流分类方法

https://www.sciencedirect.com/science/article/pii/S0167739X22000474highlights•我们设计了一种特征选择方法来选择独立和相关的特征。•我们设计了一种方法来识别物联网和复杂的 DDoS 攻击流。•该体系结构在有效性和效率方面优于比较方法。摘要分布式拒绝服务 (DDoS) 攻击…

CentOS8基础篇3:使用vim编辑文档

一、vim编辑器 vim 编辑器共有三种工作模式&#xff0c;分别是命令模式、输入模式和末行模式。 〖例2.24〗使用vim编辑器创建并编辑文件hello.c。 二、查看文件内容命令 1. more/less 浏览文件全部内容 当文件内容过多时&#xff0c;可以用more或less命令来查看。 命令格式…

HTTP缓存看这一篇就够了

前言 HTTP缓存机制是优化web性能的重要手段&#xff0c;也是优化用户体验的重要一环。了解和熟悉HTTP缓存机制也成为了前端工作者必不可少的技能。 HTTP缓存是用于临时存储网页资源&#xff08;如HTML页面、图像等&#xff09;&#xff0c;以减少服务器延迟的一种技术。HTTP缓…

nim语言在不同操作系统安装

官网&#xff1a; Nim Programming Language 学习文档&#xff1a; Nim文档概述 Tutorial (part I)The Nim one deals with basics. 官方下载地址&#xff1a;Download - Nim Programming Language 目录 Mac OS Ubuntu centos Mac OS 安装语言 brew install nim 安装…

nodejs基于vue的饭店点餐外卖平台网站

本系统主要实现了管理员&#xff1a;首页、个人中心、用户管理、菜品分类管理、菜品信息管理、菜品评价管理、系统管理、订单管理,用户&#xff1a;首页、个人中心、菜品评价管理、我的收藏管理、订单管理,前台首页&#xff1a;首页、菜品信息、菜品资讯、个人中心、后台管理、…

尚医通(九)数据字典模块前后端 | EasyExcel

目录一、数据字典介绍1、什么是数据字典2、页面展示效果3、数据字典表设计4、数据分析5、根据页面效果分析数据接口二、搭建数据字典模块三、数据字典列表接口1、model模块添加数据字典实体2、添加数据字典mapper3、添加数据字典service4、添加数据字典controller四、数据字典列…