Files
keyboard/keyBoard/VC/KBPermissionViewController.m
2025-11-27 21:39:03 +08:00

298 lines
10 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// KBPermissionViewController.m
// CustomKeyboard
//
// Created by Mac on 2025/10/27.
//
#import "KBPermissionViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface KBPermissionViewController ()
@property (nonatomic, strong) UILabel *titleLabel; // 标题
@property (nonatomic, strong) UILabel *tipsLabel; // 步骤提示
@property (nonatomic, strong) UIButton *openButton; // 去设置
@property (nonatomic, strong) UIButton *closeButton; // 去设置
@property (nonatomic, strong) UILabel *helpLabel; // 底部帮助
@property (nonatomic, strong) UIImageView *redImageView;
@property (nonatomic, strong) UIImageView *bgImageView;
// 权限引导视频播放器(循环播放,不提供暂停交互)
@property (nonatomic, strong) AVPlayer *kb_permPlayer;
@property (nonatomic, strong) AVPlayerLayer *kb_permPlayerLayer;
@end
@implementation KBPermissionViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.bgImageView];
[self.view addSubview:self.redImageView];
// 懒加载控件 + 添加到视图
[self.view addSubview:self.closeButton];
[self.view addSubview:self.titleLabel];
[self.view addSubview:self.tipsLabel];
// [self.view addSubview:self.videoContainerView];
[self.view addSubview:self.openButton];
[self.view addSubview:self.helpLabel];
[self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// Masonry 约束
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(20);
make.width.mas_equalTo(26);
make.height.mas_equalTo(26);
}];
[self.redImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.closeButton.mas_centerY);
make.right.equalTo(self.view).offset(20);
make.width.mas_equalTo(143);
make.height.mas_equalTo(132);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.closeButton.mas_bottom).offset(13);
make.left.equalTo(self.view).offset(22);
make.height.mas_equalTo(24);
}];
[self.tipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).offset(8);
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);
// }];
[self.openButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.view).offset(-KB_SAFE_BOTTOM-20);
make.left.equalTo(self.view).offset(47);
make.right.equalTo(self.view).offset(-47);
make.height.mas_equalTo(60);
}];
// [self.helpLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.equalTo(self.openButton.mas_bottom).offset(12);
// make.left.equalTo(self.view).offset(24);
// make.right.equalTo(self.view).offset(-24);
// }];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 进入页面时自动开始播放
[self kb_setupPermissionVideoPlayer];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
// 页面离开时停止播放,避免声音继续在其他界面播放
[self.kb_permPlayer pause];
}
- (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);
}
- (void)dealloc {
// 移除通知监听
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Actions
- (void)onBack {
// 支持两种展示方式:
// 1) 作为子控制器嵌入(无 presentingViewController→ 交由回调让父 VC 处理(通常 pop
// 2) 作为模态弹出 → 按原策略先 pop 再 dismiss
UIViewController *presenter = self.presentingViewController;
if (!presenter) {
if (self.backHandler) self.backHandler();
return;
}
UINavigationController *nav = nil;
if ([presenter isKindOfClass:UINavigationController.class]) {
nav = (UINavigationController *)presenter;
} else if (presenter.navigationController) {
nav = presenter.navigationController;
}
if (nav) {
[nav popViewControllerAnimated:NO];
[nav dismissViewControllerAnimated:YES completion:^{ if (self.backHandler) self.backHandler(); }];
} else {
[self dismissViewControllerAnimated:YES completion:^{ if (self.backHandler) self.backHandler(); }];
}
}
- (void)openSettings {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
UIApplication *app = [UIApplication sharedApplication];
if ([app canOpenURL:url]) {
if (@available(iOS 10.0, *)) {
[app openURL:url options:@{} completionHandler:nil];
} else {
[app openURL:url];
}
}
}
- (void)closeButtonAction{
[self.navigationController popViewControllerAnimated:true];
}
#pragma mark - Video Player
// 初始化并开始在 cardView 中循环播放视频
- (void)kb_setupPermissionVideoPlayer {
// 避免重复初始化
if (self.kb_permPlayer) {
[self.kb_permPlayer play];
return;
}
NSURL *videoURL = [[NSBundle mainBundle] URLForResource:@"permiss_video" withExtension:@"mp4"];
if (!videoURL) {
return;
}
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoURL];
self.kb_permPlayer = [AVPlayer playerWithPlayerItem:item];
self.kb_permPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
self.kb_permPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.kb_permPlayer];
// 使用等比模式,按我们计算好的 frame 显示;多余部分由容器裁剪
self.kb_permPlayerLayer.videoGravity = AVLayerVideoGravityResize;
self.kb_permPlayerLayer.cornerRadius = 20;
self.kb_permPlayerLayer.masksToBounds = true;
// 将视频图层插在按钮下面,保证按钮显示在视频之上
CALayer *buttonLayer = self.openButton.layer;
[self.view.layer insertSublayer:self.kb_permPlayerLayer below:buttonLayer];
// 播放结束后从头循环
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(kb_playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:item];
[self.kb_permPlayer play];
}
- (void)kb_playerItemDidReachEnd:(NSNotification *)note {
AVPlayerItem *item = (AVPlayerItem *)note.object;
if (!item) return;
__weak typeof(self) weakSelf = self;
[item seekToTime:kCMTimeZero completionHandler:^(BOOL finished) {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf.kb_permPlayer play];
}];
}
#pragma mark - Lazy Subviews
- (UIButton *)backButton {
if (!_backButton) {
_backButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_backButton setTitle:KBLocalized(@"common_back") forState:UIControlStateNormal];
_backButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
[_backButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
[_backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
}
return _backButton;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [UILabel new];
_titleLabel.text = (@"key of love keyboard");
_titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold];
_titleLabel.textColor = [UIColor blackColor];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
- (UILabel *)tipsLabel {
if (!_tipsLabel) {
_tipsLabel = [UILabel new];
_tipsLabel.text = (@"One-click to find a partner");
_tipsLabel.font = [UIFont systemFontOfSize:14];
_tipsLabel.textColor = [UIColor darkGrayColor];
_tipsLabel.textAlignment = NSTextAlignmentCenter;
}
return _tipsLabel;
}
- (UIButton *)openButton {
if (!_openButton) {
_openButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_openButton setTitle:@"Turn on the keyboard" forState:UIControlStateNormal];
_openButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
[_openButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_openButton.backgroundColor = [UIColor colorWithHex:KBBlackValue];
_openButton.layer.cornerRadius = 30;
[_openButton addTarget:self action:@selector(openSettings) forControlEvents:UIControlEventTouchUpInside];
}
return _openButton;
}
- (UIButton *)closeButton {
if (!_closeButton) {
_closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_closeButton setImage:[UIImage imageNamed:@"close_icon"] forState:UIControlStateNormal];
[_closeButton addTarget:self action:@selector(closeButtonAction) forControlEvents:UIControlEventTouchUpInside];
}
return _closeButton;
}
- (UILabel *)helpLabel {
if (!_helpLabel) {
_helpLabel = [UILabel new];
_helpLabel.text = KBLocalized(@"perm_help");
_helpLabel.font = [UIFont systemFontOfSize:12];
_helpLabel.textColor = [UIColor grayColor];
_helpLabel.textAlignment = NSTextAlignmentCenter;
_helpLabel.numberOfLines = 2;
}
return _helpLabel;
}
- (UIImageView *)bgImageView{
if (!_bgImageView) {
_bgImageView = [[UIImageView alloc] init];
_bgImageView.image = [UIImage imageNamed:@"qx_bg_icon"];
}
return _bgImageView;
}
- (UIImageView *)redImageView{
if (!_redImageView) {
_redImageView = [[UIImageView alloc] init];
_redImageView.image = [UIImage imageNamed:@"qx_ax_icon"];
}
return _redImageView;
}
@end