1
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#import "KBPermissionViewController.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSizeContext;
|
||||
|
||||
@interface KBPermissionViewController ()
|
||||
@property (nonatomic, strong) UILabel *titleLabel; // 标题
|
||||
@property (nonatomic, strong) UILabel *tipsLabel; // 步骤提示
|
||||
@@ -23,6 +25,9 @@
|
||||
@property (nonatomic, strong) AVPlayer *kb_permPlayer;
|
||||
@property (nonatomic, strong) AVPlayerLayer *kb_permPlayerLayer;
|
||||
|
||||
// 承载视频的裁剪容器,高度固定为 KBFit(550),内部内容从顶部开始显示,超出的部分从底部裁剪
|
||||
@property (nonatomic, strong) UIView *videoContainerView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBPermissionViewController
|
||||
@@ -36,7 +41,7 @@
|
||||
[self.view addSubview:self.closeButton];
|
||||
[self.view addSubview:self.titleLabel];
|
||||
[self.view addSubview:self.tipsLabel];
|
||||
// [self.view addSubview:self.videoContainerView];
|
||||
[self.view addSubview:self.videoContainerView];
|
||||
[self.view addSubview:self.openButton];
|
||||
[self.view addSubview:self.helpLabel];
|
||||
|
||||
@@ -70,13 +75,13 @@
|
||||
make.left.equalTo(self.titleLabel);
|
||||
}];
|
||||
|
||||
// 视频容器:左右距离 view 16,顶部距离 tipsLabel 30,底部距离按钮 36
|
||||
// [self.videoContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
// make.top.equalTo(self.tipsLabel.mas_bottom).offset(30);
|
||||
// make.left.equalTo(self.view).offset(16);
|
||||
// make.right.equalTo(self.view).offset(-16);
|
||||
// make.bottom.equalTo(self.openButton.mas_top).offset(-36);
|
||||
// }];
|
||||
// 视频容器:左右各 25,顶部距离 tipsLabel 32,高度固定为 KBFit(550)
|
||||
[self.videoContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(self.tipsLabel.mas_bottom).offset(32);
|
||||
make.left.equalTo(self.view).offset(25);
|
||||
make.right.equalTo(self.view).offset(-25);
|
||||
make.height.mas_equalTo(KBFit(550));
|
||||
}];
|
||||
|
||||
[self.openButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.equalTo(self.view).offset(-KB_SAFE_BOTTOM-20);
|
||||
@@ -107,13 +112,32 @@
|
||||
- (void)viewDidLayoutSubviews {
|
||||
[super viewDidLayoutSubviews];
|
||||
if (!self.kb_permPlayerLayer) { return; }
|
||||
// 直接铺满整个视图区域,由 videoGravity 负责等比缩放
|
||||
self.kb_permPlayerLayer.frame = CGRectMake(25, CGRectGetMaxY(self.tipsLabel.frame) + 32, KB_SCREEN_WIDTH - 50, 700);
|
||||
// 以「宽度」为基准等比缩放视频,高度按宽高比计算,从 videoContainerView 顶部对齐,
|
||||
// 多出的部分由容器(固定高度 KBFit(550))从底部裁剪
|
||||
CGSize videoSize = self.kb_permPlayer.currentItem.presentationSize;
|
||||
if (videoSize.width <= 0) { return; } // 尚未拿到真实尺寸时先不布局
|
||||
|
||||
CGFloat aspect = videoSize.height / videoSize.width;
|
||||
CGRect containerBounds = self.videoContainerView.bounds;
|
||||
if (CGRectIsEmpty(containerBounds)) { return; }
|
||||
|
||||
CGFloat width = CGRectGetWidth(containerBounds); // 以容器宽度为基准
|
||||
CGFloat height = width * aspect; // 按宽度等比算出真实视频高度
|
||||
|
||||
// 顶部对齐,y = 0;若 height > 容器高度,则底部会被裁剪
|
||||
self.kb_permPlayerLayer.frame = CGRectMake(0, 0, width, height);
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
// 移除通知监听
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
@try {
|
||||
[self.kb_permPlayer.currentItem removeObserver:self
|
||||
forKeyPath:@"presentationSize"
|
||||
context:KBPermPlayerPresentationSizeContext];
|
||||
} @catch (__unused NSException *e) {
|
||||
// ignore if observer not set
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
@@ -180,13 +204,18 @@
|
||||
|
||||
self.kb_permPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.kb_permPlayer];
|
||||
// 使用等比模式,按我们计算好的 frame 显示;多余部分由容器裁剪
|
||||
self.kb_permPlayerLayer.videoGravity = AVLayerVideoGravityResize;
|
||||
self.kb_permPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
|
||||
self.kb_permPlayerLayer.cornerRadius = 20;
|
||||
self.kb_permPlayerLayer.masksToBounds = true;
|
||||
|
||||
// 将视频图层插在按钮下面,保证按钮显示在视频之上
|
||||
CALayer *buttonLayer = self.openButton.layer;
|
||||
[self.view.layer insertSublayer:self.kb_permPlayerLayer below:buttonLayer];
|
||||
// 将视频图层添加到裁剪容器内部,由容器控制圆角与裁剪
|
||||
[self.videoContainerView.layer addSublayer:self.kb_permPlayerLayer];
|
||||
|
||||
// 监听 presentationSize 变化,尺寸从 {0,0} 变为真实值时触发布局
|
||||
[item addObserver:self
|
||||
forKeyPath:@"presentationSize"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:KBPermPlayerPresentationSizeContext];
|
||||
|
||||
// 播放结束后从头循环
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
@@ -208,6 +237,20 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
||||
context:(void *)context {
|
||||
if (context == KBPermPlayerPresentationSizeContext) {
|
||||
// presentationSize 从 {0,0} 变为真实尺寸时,触发布局更新
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.view setNeedsLayout];
|
||||
});
|
||||
return;
|
||||
}
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
|
||||
#pragma mark - Lazy Subviews
|
||||
|
||||
- (UIButton *)backButton {
|
||||
@@ -243,7 +286,6 @@
|
||||
return _tipsLabel;
|
||||
}
|
||||
|
||||
|
||||
- (UIButton *)openButton {
|
||||
if (!_openButton) {
|
||||
_openButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
@@ -286,6 +328,7 @@
|
||||
}
|
||||
return _bgImageView;
|
||||
}
|
||||
|
||||
- (UIImageView *)redImageView{
|
||||
if (!_redImageView) {
|
||||
_redImageView = [[UIImageView alloc] init];
|
||||
@@ -294,4 +337,14 @@
|
||||
return _redImageView;
|
||||
}
|
||||
|
||||
- (UIView *)videoContainerView {
|
||||
if (!_videoContainerView) {
|
||||
_videoContainerView = [UIView new];
|
||||
_videoContainerView.backgroundColor = [UIColor clearColor];
|
||||
_videoContainerView.layer.cornerRadius = 20.0;
|
||||
_videoContainerView.clipsToBounds = YES; // 超出容器高度的部分直接裁剪
|
||||
}
|
||||
return _videoContainerView;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user